JDK-7185778 : javah error "Not a valid class name" on class names with dollar signs
  • Type: Bug
  • Component: tools
  • Sub-Component: javah
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: linux_ubuntu
  • CPU: x86
  • Submitted: 2012-07-20
  • Updated: 2013-06-26
  • Resolved: 2012-09-17
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8
7u40 b08Fixed 8Fixed
Description
FULL PRODUCT VERSION :
java version "1.7.0_03"
OpenJDK Runtime Environment (IcedTea7 2.1.1pre) (7~u3-2.1.1~pre1-1ubuntu3)
OpenJDK 64-Bit Server VM (build 22.0-b10, mixed mode)

Also tested:


java version "1.7.0_05"
Java(TM) SE Runtime Environment (build 1.7.0_05-b05)
Java HotSpot(TM) 64-Bit Server VM (build 23.1-b03, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Linux localhost 3.2.0-26-generic #41-Ubuntu SMP Thu Jun 14 17:49:24 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
I use javah to use JNI with Scala, and need to be able to run javah on classes that contain dollar signs, such as mypackage.MyClass$, since that is how Scala compiles static/singleton methods. In java 6, this worked fine, but there is a regression in java 7 (both openjdk and oracle JDK) that exits with:

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)

This appears to be due to a refactoring in isJavaIdentifierPart.

Also see http://stackoverflow.com/questions/10669704/error-with-javah-when-writing-jni-in-scala-with-java-7 for more detailed analysis of what changed.

REGRESSION.  Last worked in version 6u31

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Compile scala file (see source code for an executable test case)

2. Run command: javah -classpath target/scala-2.9.1/classes -d target/jni mypackage.MyClass$


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Creates .h files with no console output.
ACTUAL -
Exits with error message "Not a valid class name: mypackage.MyClass"

ERROR MESSAGES/STACK TRACES THAT OCCUR :
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)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package mypackage
object MyClass {
    System.loadLibrary("myclass-native")
    @native def foo(): Int = sys.error("")
}
---------- END SOURCE ----------

Comments
EVALUATION The problem is in com/sun/tools/javah/JavahTask.java:run. It calls 'internalize' on the classes on the cmd line. Here is the internalize method: private List<String> internalize(List<String> classes) { List<String> l = new ArrayList<String>(); for (String c: classes) { l.add(c.replace('$', '.')); } return l; }
2012-07-24