Unable to find a javac compiler
In Tomcat, Jetty, or another servlet container, you may receive an error stating the javac compiler can't be found. The obvious reason is if you are running from a JRE and not a JDK, however, it can still happen even when running a JDK.
The following is a typical error message: <geshi> HTTP ERROR: 500
Unable to find a javac compiler; com.sun.tools.javac.Main is not on the classpath. Perhaps JAVA_HOME does not point to the JDK. It is currently set to "/java/jdk1.6.0_17/jre"
RequestURI=/web/ Caused by:
Unable to find a javac compiler; com.sun.tools.javac.Main is not on the classpath. Perhaps JAVA_HOME does not point to the JDK. It is currently set to "/app/java/jdk1.6.0_17/jre" at org.apache.tools.ant.taskdefs.compilers.CompilerAdapterFactory.getCompiler(CompilerAdapterFactory.java:108) at org.apache.tools.ant.taskdefs.Javac.compile(Javac.java:1058) at org.apache.tools.ant.taskdefs.Javac.execute(Javac.java:882) at org.apache.jasper.compiler.Compiler.generateClass(Compiler.java:382) at org.apache.jasper.compiler.Compiler.compile(Compiler.java:472) at org.apache.jasper.compiler.Compiler.compile(Compiler.java:451) at org.apache.jasper.compiler.Compiler.compile(Compiler.java:439) at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:511) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:295) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:292) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:236) at javax.servlet.http.HttpServlet.service(HttpServlet.java:820) at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502) at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:363) at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181) at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:757) at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:416) at org.mortbay.jetty.servlet.Dispatcher.forward(Dispatcher.java:334) at org.mortbay.jetty.servlet.Dispatcher.forward(Dispatcher.java:126) at org.mortbay.jetty.servlet.DefaultServlet.doGet(DefaultServlet.java:463) at javax.servlet.http.HttpServlet.service(HttpServlet.java:707) at javax.servlet.http.HttpServlet.service(HttpServlet.java:820) </geshi>
You can verify the running JVM properties using the jinfo command. Example:
<geshi> /java/jdk1.6.0_17/bin/jinfo -sysprops 26314 | grep java.home Attaching to process ID 26314, please wait... Debugger attached successfully. Server compiler detected. JVM version is 14.3-b01 java.home = /java/jdk1.6.0_17/jre </geshi>
The easiest solution is to copy the tools.jar into the lib directory.
<geshi> cp -p /java/jdk1.6.0_17/lib/tools.jar /java/jdk1.6.0_17/jre/lib/ </geshi>
Alternatively, you can specify tools.jar on the classpath. For example: <geshi> $ /java/jdk1.6.0_17/bin/java -cp /java/jdk1.6.0_17/lib/tools.jar com.sun.tools.javac.Main Usage: javac <options> <source files> where possible options include:
-g Generate all debugging info
-g:none Generate no debugging info
-g:{lines,vars,source} Generate only some debugging info
-nowarn Generate no warnings
-verbose Output messages about what the compiler is doing
-deprecation Output source locations where deprecated APIs are used
-classpath <path> Specify where to find user class files and annotation processors
-cp <path> Specify where to find user class files and annotation processors
-sourcepath <path> Specify where to find input source files
-bootclasspath <path> Override location of bootstrap class files
-extdirs <dirs> Override location of installed extensions
-endorseddirs <dirs> Override location of endorsed standards path
-proc:{none,only} Control whether annotation processing and/or compilation is done.
-processor <class1>[,<class2>,<class3>...]Names of the annotation processors to run; bypasses default discovery process
-processorpath <path> Specify where to find annotation processors
-d <directory> Specify where to place generated class files
-s <directory> Specify where to place generated source files
-implicit:{none,class} Specify whether or not to generate class files for implicitly referenced files
-encoding <encoding> Specify character encoding used by source files
-source <release> Provide source compatibility with specified release
-target <release> Generate class files for specific VM version
-version Version information
-help Print a synopsis of standard options
-Akey[=value] Options to pass to annotation processors
-X Print a synopsis of nonstandard options
-J<flag> Pass <flag> directly to the runtime system
</geshi>