In java 6, I was able to use JNI in Scala just fine. I would have code like:
package mypackage
object MyClass {
System.loadLibrary("myclass-native")
@native def foo(): Int = sys.error("")
}
And then I’d run:
javah -classpath target/scala-2.9.1/classes -d target/jni mypackage.MyClass$
And I’d get my header files just fine.
In java 7, I get the following error:
Exception in thread "main" java.lang.IllegalArgumentException: Not a valid class name: mypackage.MyClass.
at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:177)
at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:68)
at com.sun.tools.javah.JavahTask.run(JavahTask.java:509)
at com.sun.tools.javah.JavahTask.run(JavahTask.java:335)
at com.sun.tools.javah.Main.main(Main.java:46)
It’s like javah no longer accepts dollar signs in class names, but I need to use the dollar sign in Scala to get the equivalent of a static method.
For reference with java 6:
$ java -version
java version "1.6.0_29"
Java(TM) SE Runtime Environment (build 1.6.0_29-b11)
Java HotSpot(TM) 64-Bit Server VM (build 20.4-b02, mixed mode)
$ javah -version
javah version "1.6.0_29"
With java 7:
$ java -version
java version "1.7.0_03"
OpenJDK Runtime Environment (IcedTea7 2.1.1pre) (7~u3-2.1.1~pre1-1ubuntu2)
OpenJDK 64-Bit Server VM (build 22.0-b10, mixed mode)
$ javah -version
javah version "1.7.0_03"
Has anyone had any luck using javah for JNI with Scala in java 7?
Edit
Posted as a bug at https://bugs.java.com/bugdatabase/view_bug?bug_id=7185778
The best way to get some understanding of what is happening is to directly go to the sources through OpenJDK website. If we look to
com.sun.tools.javac.api.JavacTool}
You can see the offending line:
So now let’s have a look to javax.lang.model.SourceVersion
So you can see that the method which we were expecting to return true (but is instead returning false) is:
And the problem is
!Character.isJavaIdentifierPart(cp)Now if we look to the 1.6 version:
And the 1.7 version:
Some refactoring has occurred here, and if you look to CharacterData of you discover that it returns some classes which are generated on the fly from templates in
/openjdk/make/tools/GenerateCharacter/CharacterData**.java.templatewhen building java distribution:I think you could try to run javah in debug mode and see what happens in the two cases, then send a precise bug report to the OpenJDK guys, because the bug has clearly been introduced by this refactoring.