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>