Self-executing war with embedded Jetty server (not the plugin)


(Abhijit Sarkar) #1

I’m have a Groovy project that should run as a self-executing war with embedded Jetty server and I have the following set up so far. Unfortunately, I get a

ClassNotFoundException: groovy.lang.GroovyObject

when I execute the jar. What am I missing?

apply plugin: 'war'
  configurations {
    embeddedJetty
}
  dependencies {
    compile project(':movie-manager-domain')
    compile(
            [group: 'org.glassfish.jersey.core', name: 'jersey-server', version: jerseyVersion],
            [group: 'org.glassfish.jersey.containers', name: 'jersey-container-servlet-core', version: jerseyVersion],
            [group: 'com.fasterxml.jackson.jaxrs', name: 'jackson-jaxrs-json-provider', version: jacksonVersion]
    )
    runtime(
            [group: 'org.jboss.weld.servlet', name: 'weld-servlet', version: weldServletVersion]
    )
    embeddedJetty(
            [group: 'org.eclipse.jetty', name: 'jetty-server', version: jettyVersion],
            [group: 'org.eclipse.jetty', name: 'jetty-servlet', version: jettyVersion],
            [group: 'org.eclipse.jetty', name: 'jetty-webapp', version: jettyVersion],
            [group: 'org.eclipse.jetty', name: 'jetty-annotations', version: jettyVersion],
            [group: 'org.eclipse.jetty', name: 'jetty-jndi', version: jettyVersion],
            [group: 'org.eclipse.jetty', name: 'jetty-plus', version: jettyVersion]
    )
    providedCompile(
            [group: 'javax', name: 'javaee-web-api', version: javaeeVersion]
    )
}
  sourceSets {
    [main, test].each {
        it.compileClasspath += project.configurations.providedCompile + project.configurations.embeddedJetty
        it.runtimeClasspath += project.configurations.providedCompile
    }
}
  war {
    // Unzip and add all jetty dependencies into the root of the war file
    from {
        configurations.embeddedJetty.collect {
            project.zipTree(it)
        }
    }
    // Remove unnecessary files
    exclude 'META-INF/*.SF', 'META-INF/*.RSA', 'about.html', 'about_files/**', 'readme.txt',
            'plugin.properties', 'jetty-dir.css'
      // Exclude application classes from being copied to the root of the war; those are in WEB-INF/classes anyway
    from "$buildDir/classes/main"
    exclude 'name/abhijitsarkar/moviemanager/web'
      // Set the main class to run when the generate war be executed using 'java -jar'
    doFirst {
        def manifestClasspath = project.sourceSets.main.runtimeClasspath.collect { "WEB-INF/lib/${it.name}" }.join(' ')
        manifest {
            attributes(
                    'Main-Class': 'name.abhijitsarkar.moviemanager.EmbeddedJettyServer'
//
                  'Class-Path': manifestClasspath
            )
        }
    }
}

(Abhijit Sarkar) #2

I figured this out. All dependencies of embeddedJetty configuration need to be declared in the same block, so that those can later be extracted at the root of the war.The main class is not loaded with the Web application classloader and hence does not have access to WEB-INF/lib jars. Here’s a working build file for anyone who runs into the same issue. https://github.com/abhijitsarkar/groovy/blob/master/movie-manager/movie-manager-web/build.gradle


(Abhijit Sarkar) #3

One suggestion to the community. Why not remove the embedded Gradle plugin or at least put up a deprecated alert on the Wiki page. I spent hours trying to figure out why it doesn’t work before stumbling across a post that said it was built for Jetty 6.