Sigge
Sigge

Reputation: 23

Spring boot war deployment to jetty

I'm creating a spring-boot app using maven as build tool.

I've got an issue where I want to create a .war file and deploy it to a dedicated jetty instance.

The error i get is the following:

Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFactory.

This is solved when i remove the dependency to the org.apache.juli lib by excluding the lib that is a dependency in the spring-boot-starter.jdbc:

pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    <exclusions>
        <exclusion>
             <groupId>org.apache.tomcat</groupId>
             <artifactId>tomcat-juli</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Excluding this library makes the war run on the current version of jetty (jetty-distribution-9.3.8.v20160314).

HOWEVER: When I try to start the JAVA APP i.e. by using the main and embedded jetty server it craches with the following message:

Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFactory.

I.e. the same error like the .war file got in dedicated jetty instance -.-. By including the org.apache.toimcat -> tomcat.juli again I can start it thorugh the main method again but not build a .war file that runs on the jetty instance....

My main class contains the following two methods (and is annotated with @SpringBootApplication):

protected SpringApplicationBuilder configure(SpringApplicationBuilder app) {
    application.sources(App.class);
    return super.configure(app);
}

public static void main(String[] args) throws Exception {
    SpringApplication.run(App.class, args);
}

Can anyone help me with this/point in the right direction?? I'd like to use the same configuration for .war and standalone usage.

POM.xml:`Thank you for answer, the pom.xml is in this comment:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>my.company</groupId>
    <artifactId>testing</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <properties>
        <java.version>1.8</java.version>
        <start-class>my.company.App</start-class>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                 <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <!-- Additional lines to be added here... -->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
            <!-- <exclusions>
                <exclusion>
                    <groupId>org.apache.tomcat</groupId>
                    <artifactId>tomcat-juli</artifactId>
                </exclusion>
            </exclusions>-->
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-hateoas</artifactId>
        </dependency>
        <!-- com.oracle -->
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc6</artifactId>
            <version>11.2.0.3</version>
        </dependency>
    </dependencies>
</project>

Upvotes: 2

Views: 3506

Answers (1)

Alexey Mitrofanov
Alexey Mitrofanov

Reputation: 61

Generally there's no way to have single pom.xml configuration both for '.war' and for executable '.jar' with appropriate dependency management differences. Though I understand you'd like to develop and test it as executable, while deploying as '.war'.

Perfect solution is to use Maven profiles for that. So you can have default profile for '.war' packaging, with that juli excluded. And you can have some 'JarExecutable' profile, where you include it back and describe all other differences from default.

Other solution, which is also not so bad and often helps, configure all those dependencies that are Jetty specific as provided. Spring Boot packaging include it to executable jars, while they are omitted (or packaged to separate directory, which is not included to classpath by default) when packaging '.war'.

Upvotes: 1

Related Questions