You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It looks like there is a new issue with swift 3.1. Since the upgrade there was a number of warning and the thread crashes during the JVM creation:
-> 0x10f5002b4: movl (%rsi), %eax
0x10f5002b6: leaq 0xf8(%rbp), %rsi
0x10f5002bd: vmovdqu %ymm0, (%rsi)
0x10f5002c1: vmovdqu %ymm7, 0x20(%rsi)
0x10f5002c6: vmovdqu %ymm8, 0x40(%rsi)
0x10f5002cb: vmovdqu %ymm15, 0x60(%rsi)
In particular There is a warning I am very suspicious of:
warning: 'unsafeBitCast' from 'UnsafeMutablePointer' to 'UnsafeMutablePointer<UnsafeMutableRawPointer?>' (aka 'UnsafeMutablePointer<Optional>') changes pointee type and may lead to undefined behavior; use the 'withMemoryRebound' method on 'UnsafeMutablePointer' to rebind the type of memory
return try body( unsafeBitCast( ptr, to: UnsafeMutablePointer<UnsafeMutableRawPointer?>.self ) )
I am running with Java 1.8 from Oracle on Sierra 10.12. I get a segmentation fault. The real bizzare thing I that if I force the thread to continue it actually load the JVM.
Swift module manager
I have a Swift application that load the JVM in the background with the are embedded in the app wrapper. We are using the JVM as server to call Java libraries.
func findAndLoadJVM() {
do {
print("JVM arguments \(self.args)")
// We need to first find the right JRE
do {
let jreBundle = args.jreBundle!
let jreBundleLoaded: Bool = ((try? jreBundle.loadAndReturnError()) != nil)
if (!jreBundleLoaded) {
throw JVMError.failToLoadRequestedJVM
}
} catch let error as NSError {
print("Error: \(error.domain)")
throw JVMError.failToLoadRequestedJVM
}
// Now initialize it
if (JNI.initJVM(options: self.args.jvmOptions)) {
print("We have a JVM")
_ = JNI.AttachCurrentThread()
let mainClassName = self.args.javaMainClass.replacingOccurrences(of: ".", with: "/")
JNI.CachedFindClass(mainClassName, &JavaAppLauncher.mainClassCache)
if (JavaAppLauncher.mainClassCache == nil) {
// Could not find the main class
throw JVMError.failToFindMainClass
} else {
print("We have a main class \(mainClassName)")
var __args = [jvalue]( repeating: jvalue(), count: 1 )
var __locals = [jobject]()
__args[0] = JNIType.encode( value: self.args.jvmArguments, locals: &__locals )
JNIMethod.CallStaticVoidMethod(className: mainClassName, classCache: &JavaAppLauncher.mainClassCache, methodName: "main", methodSig: "([Ljava/lang/String;)V", methodCache: &JavaAppLauncher.mainMethodCache, args: &__args, locals: &__locals)
}
defer {
JNI.DetachCurrentThread()
}
} else {
// Could not initialize the JVM
throw JVMError.failToInitialize
}
} catch let e {
print("Error while instantiating the JVM " + e.localizedDescription)
}
}
I’ve pushed some small changes to the java_util package due to a duplicated implementation of clone() and rebuilt and retested using SPM the examples project using jdk1.8.0_131 and it seems to work. I don’t think the new warnings you mention are the problem or things wouldn’t work at all!
What is the path to the JDK bundle you are loading?
I imagine you’re having a threading problem related to attaching/detaching the JVM. In theory the java_swift code attaches and leaves attatched the current thread when you calll JNI.initJVM so you shouldn’t need to attach it yourself. I’d also remove the explict deferred detach as there is a cache of attached JVMs used for JNI.env which may get out of sync though why this would be a problem suddenly on Swift 3.1 I don’t know.
JNI_OnLoad is intended for Android and I’d not worry about it.
I don't think it is an issue with the attach/detach The first call never returns "JNI.initJVM(options: self.args.jvmOptions)" I traced it and the JNI_CreateJavaVM( &self.jvm, $0, &vmArgs ) crashes.
Is this an AppKit application? I’ve never been able to use the Oracle JDK from inside Xcode. Also, have you tried not loading the bundle to select the JDK. That’s the only other thing I can think of that’s different.
Yes it is. From within Xcode it does not run. However (and I am quite ashamed not to have tried it before) when run from the finder (double click) it runs and does not report any error in the console. This is very strange and I don't really understand what is going on.
I am actually not sure. I had an app that was purely a wrapper and I never tried to run it from within Xcode. This is a new app and I have no way of turning the clock back…
The 1.6 JVM is not an option as the Java code is 1.8 dependent.
Because it run standalone and does not log anything in the console I am starting to question Xcode. This may be an artifact of running ind bug mode in Xcode. However this is really annoying, the debugger is really helpful.
I’ve never had the Orcale JVM work inside Xcode. It must interact with the debugger. Have you tried unchecking “debug executable” in the scheme? You say If you continue after the crash it works? The example program in the project works with JDK 1.8 using SPM but only 1.6 in Xcode.
Some more info here. Seems to be a project configuration/linking issue somehow. I’ve got to the point where the SwiftJava/examples target works in Xcode with the Oracle JVM but the JDBC target which uses AppKit does not. One night assume this is to do with AppKit but I’ve started a new C project for a command line program that just tries to load the JVM and it always traps in the place you show above.
Activity
spearway commentedon Apr 19, 2017
In particular There is a warning I am very suspicious of:
warning: 'unsafeBitCast' from 'UnsafeMutablePointer' to 'UnsafeMutablePointer<UnsafeMutableRawPointer?>' (aka 'UnsafeMutablePointer<Optional>') changes pointee type and may lead to undefined behavior; use the 'withMemoryRebound' method on 'UnsafeMutablePointer' to rebind the type of memory
return try body( unsafeBitCast( ptr, to: UnsafeMutablePointer<UnsafeMutableRawPointer?>.self ) )
johnno1962 commentedon Apr 19, 2017
I’ve not tested it with Swift 3.1 yet. Let me recompile everything and see if there is something that needs looking at.
johnno1962 commentedon Apr 19, 2017
Seems to work on OSX with this JVM https://support.apple.com/kb/DL1572?locale=en_GB even with the warnings.
What OS/JVM version are you using?
spearway commentedon Apr 19, 2017
I am running with Java 1.8 from Oracle on Sierra 10.12. I get a segmentation fault. The real bizzare thing I that if I force the thread to continue it actually load the JVM.
johnno1962 commentedon Apr 19, 2017
Are you using Swift Package Manager or Xcode?
spearway commentedon Apr 19, 2017
Swift module manager
I have a Swift application that load the JVM in the background with the are embedded in the app wrapper. We are using the JVM as server to call Java libraries.
spearway commentedon Apr 19, 2017
This look like an allocation issue between Java/JNI and Swift. This is why I was suspicious of the withPointerToRawPointer warning
spearway commentedon Apr 20, 2017
I also noted that the JNI_OnLoad never get called. How does this work?
johnno1962 commentedon Apr 20, 2017
I’ve pushed some small changes to the java_util package due to a duplicated implementation of clone() and rebuilt and retested using SPM the examples project using jdk1.8.0_131 and it seems to work. I don’t think the new warnings you mention are the problem or things wouldn’t work at all!
What is the path to the JDK bundle you are loading?
I imagine you’re having a threading problem related to attaching/detaching the JVM. In theory the java_swift code attaches and leaves attatched the current thread when you calll JNI.initJVM so you shouldn’t need to attach it yourself. I’d also remove the explict deferred detach as there is a cache of attached JVMs used for JNI.env which may get out of sync though why this would be a problem suddenly on Swift 3.1 I don’t know.
JNI_OnLoad is intended for Android and I’d not worry about it.
spearway commentedon Apr 20, 2017
I don't think it is an issue with the attach/detach The first call never returns "JNI.initJVM(options: self.args.jvmOptions)" I traced it and the JNI_CreateJavaVM( &self.jvm, $0, &vmArgs ) crashes.
johnno1962 commentedon Apr 20, 2017
Is this an AppKit application? I’ve never been able to use the Oracle JDK from inside Xcode. Also, have you tried not loading the bundle to select the JDK. That’s the only other thing I can think of that’s different.
spearway commentedon Apr 20, 2017
Yes it is. From within Xcode it does not run. However (and I am quite ashamed not to have tried it before) when run from the finder (double click) it runs and does not report any error in the console. This is very strange and I don't really understand what is going on.
spearway commentedon Apr 20, 2017
I did fix the warning following the method at https://swift.org/migration-guide/se-0107-migrate.html
Which has the added advantage of legibility
johnno1962 commentedon Apr 20, 2017
I may get rid of withPointerToRawPointer as you suggest. Have you tried initialising the JVM from the main thread?
spearway commentedon Apr 20, 2017
No I have not, but would it not be an issue as it would monopolize the main thread. I will have a look.
spearway commentedon Apr 20, 2017
It stops exactly at the same place on the main thread.
johnno1962 commentedon Apr 20, 2017
And this is all new to Swift 3.1? Very odd. You’ll have to take the program to pieces and put it back together part by part. Can you try the 1.6 JVM?
spearway commentedon Apr 20, 2017
I am actually not sure. I had an app that was purely a wrapper and I never tried to run it from within Xcode. This is a new app and I have no way of turning the clock back…
The 1.6 JVM is not an option as the Java code is 1.8 dependent.
spearway commentedon Apr 20, 2017
Because it run standalone and does not log anything in the console I am starting to question Xcode. This may be an artifact of running ind bug mode in Xcode. However this is really annoying, the debugger is really helpful.
johnno1962 commentedon Apr 20, 2017
I’ve never had the Orcale JVM work inside Xcode. It must interact with the debugger. Have you tried unchecking “debug executable” in the scheme? You say If you continue after the crash it works? The example program in the project works with JDK 1.8 using SPM but only 1.6 in Xcode.
spearway commentedon Apr 20, 2017
if you do "pr h -p true -n true -s false SIGSEGV" and continue it appears to work. I have not done a lot of testing yet.
johnno1962 commentedon Apr 20, 2017
Crikey, what does that do?
spearway commentedon Apr 20, 2017
it tell the debugger not to stop that thread on a SIGSEGV
This is kind of bizarre
johnno1962 commentedon Apr 20, 2017
It’s part of the “normal” code path for the JVM which traps it which is overridden by the debugger?
johnno1962 commentedon Apr 21, 2017
Some more info here. Seems to be a project configuration/linking issue somehow. I’ve got to the point where the SwiftJava/examples target works in Xcode with the Oracle JVM but the JDBC target which uses AppKit does not. One night assume this is to do with AppKit but I’ve started a new C project for a command line program that just tries to load the JVM and it always traps in the place you show above.
johnno1962 commentedon Jun 20, 2017
Filed a radar and a bug with Oracle about this: http://bugreport.java.com/bugreport/bug_info.do?bug_id=88A0C05DB15AF0C2BA2605D8BF388A37