United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-7185778 javah error "Not a valid class name" on class names with dollar signs
JDK-7185778 : javah error "Not a valid class name" on class names with dollar signs

Details
Type:
Bug
Submit Date:
2012-07-20
Status:
Closed
Updated Date:
2013-05-21
Project Name:
JDK
Resolved Date:
2012-09-17
Component:
tools
OS:
linux_ubuntu
Sub-Component:
javah
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:
7u40 (b08)

Related Reports
Backport:

Sub Tasks

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



Hardware and Software, Engineered to Work Together