I'm trying to run JSPs and Servlets using embedded Jetty. I have a standard Java application (not a web application) and it is packaged as a JAR (not a WAR) and I have a dedicated folder to store all web related files ("webui/"): web.xml, *.jsp, *.jspf, etc. This folder is in same folder as JAR and it is accessible from the application (proven).
My application works perfectly when I run it from inside NetBeans (ver. 8.1 and Java 8), but when I execute it from a shell window (java -jar myapp.jar) it provides following error
org.apache.jasper.JasperException: /menu.jsp (line: 6, column: 0) The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application
Before posting this, I've read (among many others) following posts:
Jetty 9 The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved But I'm not using Glassfish
Other posts say to place the JAR inside WEB-INF/lib. But I can not because I do not have WEB-INF folder because I do not follow a WEB app folders structure. I have it inside app ./lib/ folder (with all other jars).
Embedded Jetty Error The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved. I've used also the approach this post says and also the approach this post refers to (official Jetty example). In both cases I obtain the same error as with my code.
This is my POM
<!--Jetty dependencies start here -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jettyVersion}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>${jettyVersion}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${jettyVersion}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-annotations</artifactId>
<version>${jettyVersion}</version>
</dependency>
<!--Jetty Apache JSP -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>apache-jsp</artifactId>
<version>${jettyVersion}</version>
</dependency>
<!-- Jetty JSTL -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
This is my code
private static Server serverWeb = null;
//----------------------------------------------------------------------------//
public static void Main( String[] args )
{
JettyExampleStack instance = new JettyExampleStack();
instance.initServerWeb();
}
//----------------------------------------------------------------------------//
private void initServerWeb()
{
WebAppContext ctx = new WebAppContext();
ctx.setContextPath( "/" );
serverWeb = new Server( 8080 );
serverWeb.setHandler( ctx );
serverWeb.setStopAtShutdown( true );
serverWeb.setStopTimeout( UtilConvert.SECOND * 5 );
try
{
initServlets( ctx );
initJSPs( serverWeb, ctx );
serverWeb.start();
}
catch( Exception exc )
{
UtilDebug.log( exc );
stopdown();
}
}
private void initServlets( WebAppContext ctx ) throws Exception
{
ctx.addServlet( GetFile.class, "/getFile" );
}
private void initJSPs( Server server, WebAppContext ctx ) throws Exception
{
ctx.setResourceBase( "webui" );
ctx.setDescriptor( "web.xml" );
// ----------------------------------------------------------------
// TAKEN FROM HERE:
// https://github.com/jetty-project/embedded-jetty-jsp
// ----------------------------------------------------------------
// By default, the JSP implementation will use an internal eclipse JDT compiler.
// This will use the JDK JavaC built-in compiler.
System.setProperty( "org.apache.jasper.compiler.disablejsr199", "false" );
// Set a Servlet Temp Directory
File fTmp = new File( System.getProperty( "java.io.tmpdir" ), "jetty-jsp-tmp" );
if( ! UtilIO.createFolder( fTmp ) )
{
throw new IOException( "Can not create folder '"+ fTmp.getAbsolutePath() +"'" );
}
ctx.setAttribute("javax.servlet.context.tempdir", fTmp );
// Set Classloader of Context to be sane (needed for JSTL)
// JSP requires a non-System classloader, this simply wraps the
// embedded System classloader in a way that makes it suitable
// for JSP to use
ClassLoader jspClassLoader = new URLClassLoader( new URL[0], WebServer.class.getClassLoader() );
ctx.setClassLoader( jspClassLoader );
// The JspServlet must be named "jsp" (per JSP spec).
// Add JSP Servlet (must be named "jsp")
ServletHolder holderJsp = new ServletHolder( "jsp", JspServlet.class );
holderJsp.setInitOrder( 0 );
// Including the JSTL jars for the webapp.*/
ctx.setAttribute( "org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", ".*/[^/]*jstl.*\\.jar$" );
// Enabling the Annotation based configuration
Configuration.ClassList classlist = Configuration.ClassList.setServerDefault( server );
classlist.addBefore( "org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
"org.eclipse.jetty.annotations.AnnotationConfiguration" );
classlist.addAfter( "org.eclipse.jetty.webapp.FragmentConfiguration",
"org.eclipse.jetty.plus.webapp.EnvConfiguration",
"org.eclipse.jetty.plus.webapp.PlusConfiguration" );
}
Thank you very much in advance for your help.