I'm experiencing an issue that I do not quite get.
I've written the simplest jetty
application:HelloWorldJetty
that binds to port 8080
and always returns 'Hello World'
on http
requests.
The build is configured using gradle. When I use the gradle support netbeans plugin to debug the application, it works and I get the hello world response.
Now when I build the jar and execute it using java -jar
HelloWorldJetty.jar
, it does bind to port 8080
but all responses have status 500 - internal server error
.
I've never worked with an embedded server before and it feels like I'm missing something. Been searching around for days.
Here's the main class:
package com.helloworldjetty;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
/**
*
* @author george
*/
public class HelloWorldJetty {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
try {
Server server = new Server(8080);
server.setHandler(new AbstractHandler() {
@Override
public void handle(String string, Request rqst, HttpServletRequest hsr, HttpServletResponse hsr1) throws IOException, ServletException {
hsr1.setContentType("text/html;charset=utf-8");
hsr1.setStatus(HttpServletResponse.SC_OK);
rqst.setHandled(true);
hsr1.getWriter().println("<h1>Hello World</h1>");
}
});
server.start();
server.join();
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
}
And here's my gradle build script:
apply plugin: 'java'
sourceCompatibility = '1.7'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
// NetBeans will automatically add "run" and "debug" tasks relying on the
// "mainClass" property. You may however define the property prior executing
// tasks by passing a "-PmainClass=<QUALIFIED_CLASS_NAME>" argument.
//
// Note however, that you may define your own "run" and "debug" task if you
// prefer. In this case NetBeans will not add these tasks but you may rely on
// your own implementation.
if (!hasProperty('mainClass')) {
ext.mainClass = 'com.helloworldjetty.HelloWorldJetty'
}
repositories {
mavenCentral()
// You may define additional repositories, or even remove "mavenCentral()".
// Read more about repositories here:
// http://www.gradle.org/docs/current/userguide/dependency_management.html#sec:repositories
}
dependencies {
// TODO: Add dependencies here ...
// You can read more about how to add dependency here:
// http://www.gradle.org/docs/current/userguide/dependency_management.html#sec:how_to_declare_your_dependencies
compile group: 'javax', name: 'javaee-api', version: '7.0'
compile group: 'commons-beanutils', name: 'commons-beanutils', version: '1.8.3'
compile group: 'commons-httpclient', name: 'commons-httpclient', version: '3.1'
compile group: 'commons-collections', name: 'commons-collections', version: '3.2.1'
compile group: 'org.apache.velocity', name: 'velocity', version: '1.7'
compile group: 'commons-codec', name: 'commons-codec', version: '1.9'
compile group: 'commons-io', name: 'commons-io', version: '2.4'
compile group: 'com.google.guava', name: 'guava', version: 'r07'
compile group: 'commons-lang', name: 'commons-lang', version: '2.5'
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.3.3'
compile group: 'org.apache.httpcomponents', name: 'httpmime', version: '4.3.3'
compile group: 'javax.mail', name: 'javax.mail-api', version: '1.5.4'
compile group: 'com.googlecode.libphonenumber', name: 'libphonenumber', version: '6.2.2'
compile group: 'org.slf4j', name: 'jcl-over-slf4j', version: '1.6.1'
compile group: 'org.slf4j', name: 'slf4j-api', version: '1.6.1'
compile group: 'org.slf4j', name: 'slf4j-jdk14', version: '1.6.1'
compile group: 'commons-fileupload', name: 'commons-fileupload', version: '1.2.2'
compile group: 'commons-validator', name: 'commons-validator', version: '1.4.0'
compile group: 'org.apache.httpcomponents', name: 'httpcore', version: '4.3.2'
compile group: 'org.apache.httpcomponents', name: 'httpcore-nio', version: '4.1'
compile group: 'org.eclipse.jetty.aggregate', name: 'jetty-all', version: '9.3.4.RC0'
compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.20'
compile group: 'com.google.code.svenson', name: 'svenson', version: '1.3.8'
testCompile group: 'junit', name: 'junit', version: '4.10'
}
jar {
from(configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }) {
exclude "META-INF/*.SF"
exclude "META-INF/*.DSA"
exclude "META-INF/*.RSA"
}
manifest {
attributes 'Implementation-Title': 'HelloWorldJetty',
'Implementation-Version': 1.0,
'Built-By': System.getProperty('user.name'),
'Built-Date': new Date(),
'Built-JDK': System.getProperty('java.version'),
'Main-Class': 'com.helloworldjetty.HelloWorldJetty'
}
}
If anyone could shed some light on this issue I'd really appreciate it.
Having a self-executing uber-jar for a Jetty server is possible.
The Jetty Project even maintains a
embedded-jetty-uber-jar
example project demonstrating this.They also maintain a
embedded-jetty-live-war
example that makes a war file that is also self-executing.However, these examples both use maven with the uber-jar maven plugin.
Now to your gradle build.
Don't use the
jetty-all
artifact in your build (that's not what that artifact exists for)Use specific artifacts for the features / modules that you need.
Use a stable/released version of Jetty
9.3.0.RC0
is NOT stable, that's an unstable release candidate.As of Oct 27, 2015, the current stable Jetty version is
9.3.5.v20151012
Merge your webapp metadata (if you have any) into your uber-jar
META-INF/services
into your uber-jar