Closed mjason3 closed 10 years ago
I think this may be a symptom of #1187. Which version of Boot are you using?
@wilkinsona I'm using the 1.1.3.RELEASE. Finally, i resolved it by adding jsp-api, servlet-api with scope "provided". Btw, Is an executable jar a recommended way or SpringBoot want to enable both jar and war? If the SpringBoot want to enable both two ways, i have to say, current support is terrible. My suggestion will be if the package type is war, automatically remove the embed tomcat/jetty dependencies.
Thanks for following up. The problem you've seen should now be fixed in the 1.1.4 snapshots.
If you have no desire to deploy your application to a servlet container then, yes, an executable jar is the recommended way to package your application. What is the problem you're seeing with the current executable war support, beyond the problem you've reported here? What is it that makes you consider it to be "terrible"?
A war that's been repackaged by the Spring Boot Maven or Gradle plugin contains the embedded Tomcat/Jetty dependencies to allow it to be run as a self-contained executable or by deploying it to a Servlet container. If you know that you'll only ever deploy your application to a Servlet container you can easily build a traditional war file by not using the plugin or, in the case of Gradle, configuring it to disable repackaging.
Hi @wilkinsona , yes, the support of executable jar is cool. My goal is to use embed tomcat as a development env in IDE, and release it to a production env which is a tomcat or other web container. So i configure the package type as war. One issue is i have already reported above(glad to see it will be fixed soon) Another "issue" is i don't want my war package contains all the embed tomcat related dependencies like jasper which may result in conflicts.
@wilkinsona exclusion is a solution to exclude embed tomcat dependencies. However, SpringBoot is born to save such configuration effort. When I am switching between dev and prod, i hope there is a better way. That's why i say current war support is terrible. It's more like a feature request. :-)
i don't want my war package contains all the embed tomcat related dependencies like jasper which may result in conflicts
There is only a chance of a conflict due to the bug in 1.1.3. If you use 1.1.2 or a 1.1.4 snapshot, the jars for the embedded servlet container and its dependencies will be packaged in WEB-INF/lib-provided/
and a Servlet container will ignore them. They'll only be used when you run in development, either directly in your IDE, or using java -jar.
You're paying a small price in terms of the size of your application's war file to gain seamless movement from running as a self-contained application at development time to deploying to a Servlet container when you go into production. This is the best that Boot can do as it's impossible for us to detect at build time whether you're building your app for development or production. If you really want different binaries for development and production, then you could use a profile in your build (assuming you're using Maven) to control whether or not Boot's plugin performs its repackaging.
That makes sense. Thanks for the detailed explanation, Andy! I think the following way is good enough for my use case
its dependencies will be packaged in WEB-INF/lib-provided/ and a Servlet container will ignore them
I am using 1.1.4 and still unable to deploy the resulting war into a regular tomcat due to the embedded tomcat. I don't see lib-provided under WEB-INF. What could be wrong?
configurations {
querydslapt
provided
}
buildscript {
repositories {
maven { url "http://repo.spring.io/libs-release" }
maven { url "http://repo.spring.io/libs-snapshot" }
mavenLocal()
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.1.4.RELEASE")
classpath("org.flywaydb:flyway-gradle-plugin:3.0")
classpath("com.h2database:h2:1.4.178")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'flyway'
apply plugin: 'war'
jar {
baseName = 'netstar-content-rest-services'
version = '1.0.0'
}
war {
baseName = 'ncrs'
}
sourceCompatibility = 1.7
//applicationDefaultJvmArgs = [
// "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005"
//]
repositories {
mavenLocal()
mavenCentral()
maven { url "http://repo.spring.io/libs-release" }
maven { url "https://repository.jboss.org/nexus/content/repositories/releases" }
maven { url "http://repo.spring.io/libs-snapshot" }
}
sourceSets {
main.compileClasspath += configurations.provided
test.compileClasspath += configurations.provided
test.runtimeClasspath += configurations.provided
}
flyway {
url = "jdbc:h2:tcp://localhost/./netstar-content"
user = 'sa'
}
dependencies {
versionManagement 'io.spring.platform:platform-versions:1.0.1.RELEASE@properties'
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile("org.springframework.boot:spring-boot-starter-data-rest")
compile("com.fasterxml.jackson.core:jackson-databind")
compile("org.springframework.hateoas:spring-hateoas")
compile("org.springframework.plugin:spring-plugin-core")
compile("net.sf.ehcache:ehcache:2.8.3")
compile("org.springframework:spring-context-support")
compile("org.springframework.data:spring-data-redis")
compile("org.springframework:spring-tx")
compile("org.springframework:spring-tx-events:1.0.0.BUILD-SNAPSHOT")
compile("redis.clients:jedis")
compile("org.apache.commons:commons-pool2")
compile("com.jayway.jsonpath:json-path")
compile("com.h2database:h2")
compile("org.jsoup:jsoup:1.7.3")
compile('org.apache.commons:commons-lang3')
compile("org.apache.httpcomponents:httpclient")
compile("com.cenqua.clover:clover:3.3.0")
compile("com.jolbox:bonecp:0.8.0.RELEASE")
// for the anontation processor
querydslapt group: 'com.mysema.querydsl', name: 'querydsl-jpa', version: '2.8.0', classifier: 'apt-one-jar', transitive: false
compile group: 'org.projectlombok', name: 'lombok', version: '1.14.2'
// for compiling
compile("com.mysema.querydsl:querydsl-jpa")
compile("com.mysema.querydsl:querydsl-apt")
compile fileTree(dir: "${project.projectDir}/external/lib", includes: ['*.jar'])
testCompile("org.springframework.boot:spring-boot-starter-test")
//For tomcat
provided("org.springframework.boot:spring-boot-starter-tomcat")
compile("org.springframework.boot:spring-boot-starter-actuator")
}
//Querydsl
def generatedSrcDir = 'src/main/generated'
task createGeneratedSrcDir << {
file(generatedSrcDir).mkdirs()
}
compileJava.dependsOn createGeneratedSrcDir
compileJava {
options.compilerArgs << '-processor' << 'com.mysema.query.apt.jpa.JPAAnnotationProcessor' << '-s' << file(generatedSrcDir).absolutePath
}
clean {
delete generatedSrcDir
}
task wrapper(type: Wrapper) {
gradleVersion = '1.11'
}
You need to declare the embedded server container dependencies in a configuration named providedRuntime
as described here
@wilkinsona I have upgraded to 1.1.4 and there is a exception Exception in thread "main" java.lang.NoClassDefFoundError: javax/servlet/ServletContext
Is this configuration incorrect?
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
That configuration looks right to me. I've just double-checked by modifying the Web UI sample with the provided dependencies and a SpringBootServletInitializer
subclass. It ran successfully on Tomcat 7.0.54.
If you want me to investigate further, knowing the version of Tomcat that you're using and the full stack trace of the exception would help. Even better would be small app that reproduces the problem.
I encountered this exception only in IntelliJ community edition. However, in eclipse, everything goes well.
For the project to reproduce, you can use the jsp project in spring-boot samples.
That sounds like a bug in IntelliJ. Perhaps JetBrains can help.
@mjason3 It seems IntelliJ always has this problem. Change the Module Setting of your project, go to the dependencies tab, and set scope into compile from provided for all embed:tomcat* dependencies.
I can confirm that the IntelliJ error happens for me when I try to run a @SpringBootApplication
class directly (without using maven/gradle). It happens in both versions on IntelliJ.
It is fixed temporarily if you follow the instructions @xilin, but these changes are overridden anytime the Gradle project is reimported (and it's annoying to have to tell new devs to do this).
@xilin It works like a charm~
Can confirm that @xilin's solution works. Seems like this is an IntelliJ problem. Does anybody know if theres a ticket opened with JetBrains?
Just wanted to say this happens in NetBeans also as it runs the main class using Maven exec plugin if you right click and select Run File.. My fix was to create a maven profile that adds these with default scope and select the profile as the netbeans run configuration.
it may not be a intelij bug, just tried to change like this :+1:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>compile</scope>
</dependency>
and, everything works
well, of course.
You are working around the bug: the link above states that IJ does not manage provided dependencies properly. If you switch them to compile you're no longer affected by the bug....
Xi Lin Thank you very much for solving the problem I was having.
Regards
In my case just change the scope to compile
and generate 2 artifact one war explode
with all the elements. And other war archive
with the war exploded inside.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>compile</scope>
</dependency>
Hi,
I can run the spring boot in embeded tomcat. but after deploying to a tomcat container, i encounter this issue: Mon Jun 30 19:35:36 CST 2014 There was an unexpected error (type=Internal Server Error, status=500). org.apache.jsp.WEB_002dINF.views.documentation_jsp