Unable to find a javac compiler

From EggeWiki

Jump to: navigation, search

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:

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)

You can verify the running JVM properties using the jinfo command. Example:

/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

The easiest solution is to copy the tools.jar into the lib directory.

cp -p /java/jdk1.6.0_17/lib/tools.jar /java/jdk1.6.0_17/jre/lib/

Alternatively, you can specify tools.jar on the classpath. For example:

$ /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
Personal tools
Travelling Salesman

Get the app!