FULL PRODUCT VERSION :
java version "1.7.0_67"
Java(TM) SE Runtime Environment (build 1.7.0_67-b01)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
BACKGROUND
We are bundling the JRE for distribution with our application. We have also added tools.jar to the JRE's lib directory since the application performs runtime compilation of Java code. (Our understanding of the license terms in http://www.oracle.com/technetwork/java/javase/readme-142177.html#redistribution is that this inclusion of tools.jar with the JRE is allowed).
The JRE is stored in a subdirectory called 'jre' of the application's main installation directory.
THE PROBLEM
Our application cannot load the compiler in tools.jar when calling ToolProvider.getSystemJavaCompiler(). Instead of receiving a reference to the compiler we get a null pointer.
ANALYSIS
Analysis of the source code of ToolProvider (line 183) reveals that in the case where the library of the JRE is called 'jre' (as it is in our case), the parent directory will be searched for 'lib/tools.jar' instead of the JRE directory itself. Presumably this is for handling cases when the private JRE of an JDK is run. However, this prevents some standalone use of the JRE when ToolProvider is used to locate bundled tools.
WORKAROUND
Naming the JRE directory to something else than 'jre' solves the problem.
PROPOSED SOLUTION
That the file lookup in ToolProvider.java (line 182) is modified to work as follows:
- First look for 'lib/tools.jar' in the 'java.home' directory
- If the 'lib/tools.jar' is not found AND the directory name is 'jre', look for 'lib/tools.jar' in the parent directory instead
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Create a test program as described below. Put alongside a JRE with tools.jar added in the lib directory. Call the JRE directory 'jre'. Run with
jre\bin\java toolsjarlocator.ToolsJarLocator
(to get different result, rename directory to 'jre2')
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Message output: "Compiler found"
ACTUAL -
Message output: "Compiler NOT found"
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package toolsjarlocator;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
public class ToolsJarLocator {
public static void main(String[] args) {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
System.out.println("Compiler " + ((compiler == null) ? "NOT found" : "found"));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Never distribute bundled JREs in a directory called 'jre'.
java version "1.7.0_67"
Java(TM) SE Runtime Environment (build 1.7.0_67-b01)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
BACKGROUND
We are bundling the JRE for distribution with our application. We have also added tools.jar to the JRE's lib directory since the application performs runtime compilation of Java code. (Our understanding of the license terms in http://www.oracle.com/technetwork/java/javase/readme-142177.html#redistribution is that this inclusion of tools.jar with the JRE is allowed).
The JRE is stored in a subdirectory called 'jre' of the application's main installation directory.
THE PROBLEM
Our application cannot load the compiler in tools.jar when calling ToolProvider.getSystemJavaCompiler(). Instead of receiving a reference to the compiler we get a null pointer.
ANALYSIS
Analysis of the source code of ToolProvider (line 183) reveals that in the case where the library of the JRE is called 'jre' (as it is in our case), the parent directory will be searched for 'lib/tools.jar' instead of the JRE directory itself. Presumably this is for handling cases when the private JRE of an JDK is run. However, this prevents some standalone use of the JRE when ToolProvider is used to locate bundled tools.
WORKAROUND
Naming the JRE directory to something else than 'jre' solves the problem.
PROPOSED SOLUTION
That the file lookup in ToolProvider.java (line 182) is modified to work as follows:
- First look for 'lib/tools.jar' in the 'java.home' directory
- If the 'lib/tools.jar' is not found AND the directory name is 'jre', look for 'lib/tools.jar' in the parent directory instead
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Create a test program as described below. Put alongside a JRE with tools.jar added in the lib directory. Call the JRE directory 'jre'. Run with
jre\bin\java toolsjarlocator.ToolsJarLocator
(to get different result, rename directory to 'jre2')
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Message output: "Compiler found"
ACTUAL -
Message output: "Compiler NOT found"
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package toolsjarlocator;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
public class ToolsJarLocator {
public static void main(String[] args) {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
System.out.println("Compiler " + ((compiler == null) ? "NOT found" : "found"));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Never distribute bundled JREs in a directory called 'jre'.