Run spring-boot application on Liberty Server

Viewed 6655

I developed a stand-alone spring boot application that serves a rest service, I've packaged it as a jar and it runs correctly. In order to release it on production server (Websphere), I have to convert it into a war.

I've updated my pom.xml adding these lines:

<properties>
    <maven.compiler.target>1.7</maven.compiler.target>
    <maven.compiler.source>1.7</maven.compiler.source>
</properties>
<packaging>war</packaging>
<build>
    <finalName>${artifactId}</finalName>
</build>

Then, I launched maven clean package and I get the war. So, publishing it on a Tomcat Server works fine, but on Liberty I get the error:

Error 404: SRVE0190E: File not found /

I've also modified my entry point like the following:

@SpringBootApplication
@PropertySource("classpath:alerts.properties")
public class WebApplication extends SpringBootServletInitializer 
{

//  public static void main(String[] args) {
//      SpringApplication.run(WebApplication.class, args);
//  }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(WebApplication.class);
    }
}

With no success, so... how can I run a spring boot war on a Liberty Server?

UPDATE

As @Anjum Fatima suggested, I've also added the features in server.xml

<feature>jsp-2.3</feature>
<feature>springBoot-2.0</feature>
<feature>servlet-3.1</feature>

Before, in that file I've also added:

<library>
    <file id="alerts.properties" name="${shared.resource.dir}/alerts.properties"/>
</library>
<webApplication id="alerts" location="alerts.war" name="alerts">

And in wlp18\usr\shared\resources I've copied the properties file.

But I still have the same error.

The alert.properties file:

spring.datasource.url=jdbc:h2:file:~/alertsdb;DB_CLOSE_ON_EXIT=FALSE;AUTO_RECONNECT=TRUE
spring.datasource.username=admin
spring.datasource.password=mypassword
spring.datasource.driver-class-name=org.h2.Driver

spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update

spring.h2.console.enabled=true
spring.h2.console.settings.web-allow-others=true

spring.mvc.view.prefix: /
spring.mvc.view.suffix: .jsp
spring.messages.basename=validation

UPDATE 2

The server it's almost started, but it can't find some files like com.ibm.ws.kernel.boot.nls_1.0.22.jar, in the Liberty's lib folder there's the file com.ibm.ws.kernel.boot_1.0.22.jar (without .nls) here's the console output, what am I missing?

2020-03-18 13:44:38.950  INFO 34004 --- [ecutor-thread-4] it.mycompany.alerts.WebApplication       : Started WebApplication in 10.915 seconds (JVM running for 24.544)
[WARNING ] The XML schema [web-jsptaglibrary_2_1.xsd] could not be found. This is very likely to break XML validation if XML validation is enabled.
[WARNING ] The XML schema [javaee_5.xsd] could not be found. This is very likely to break XML validation if XML validation is enabled.
[WARNING ] The XML schema [jsp_2_1.xsd] could not be found. This is very likely to break XML validation if XML validation is enabled.
[WARNING ] The XML schema [javaee_web_services_1_2.xsd] could not be found. This is very likely to break XML validation if XML validation is enabled.
[WARNING ] The XML schema [javaee_web_services_client_1_2.xsd] could not be found. This is very likely to break XML validation if XML validation is enabled.
[WARNING ] The XML schema [web-app_3_0.xsd] could not be found. This is very likely to break XML validation if XML validation is enabled.
[WARNING ] The XML schema [web-fragment_3_0.xsd] could not be found. This is very likely to break XML validation if XML validation is enabled.
[WARNING ] The XML schema [web-common_3_0.xsd] could not be found. This is very likely to break XML validation if XML validation is enabled.
[WARNING ] The XML schema [javaee_6.xsd] could not be found. This is very likely to break XML validation if XML validation is enabled.
[WARNING ] The XML schema [jsp_2_2.xsd] could not be found. This is very likely to break XML validation if XML validation is enabled.
[WARNING ] The XML schema [javaee_web_services_1_3.xsd] could not be found. This is very likely to break XML validation if XML validation is enabled.
[WARNING ] The XML schema [javaee_web_services_client_1_3.xsd] could not be found. This is very likely to break XML validation if XML validation is enabled.
[WARNING ] The XML schema [web-app_3_1.xsd] could not be found. This is very likely to break XML validation if XML validation is enabled.
[WARNING ] The XML schema [web-fragment_3_1.xsd] could not be found. This is very likely to break XML validation if XML validation is enabled.
[WARNING ] The XML schema [web-common_3_1.xsd] could not be found. This is very likely to break XML validation if XML validation is enabled.
[WARNING ] The XML schema [javaee_7.xsd] could not be found. This is very likely to break XML validation if XML validation is enabled.
[WARNING ] The XML schema [javaee_web_services_1_4.xsd] could not be found. This is very likely to break XML validation if XML validation is enabled.
[WARNING ] The XML schema [javaee_web_services_client_1_4.xsd] could not be found. This is very likely to break XML validation if XML validation is enabled.
[WARNING ] The XML schema [web-app_4_0.xsd] could not be found. This is very likely to break XML validation if XML validation is enabled.
[WARNING ] The XML schema [web-fragment_4_0.xsd] could not be found. This is very likely to break XML validation if XML validation is enabled.
[WARNING ] The XML schema [web-common_4_0.xsd] could not be found. This is very likely to break XML validation if XML validation is enabled.
[WARNING ] The XML schema [javaee_8.xsd] could not be found. This is very likely to break XML validation if XML validation is enabled.
[WARNING ] Failed to scan [file:/C:/lang/appserver/wlp/wlp18/lib/com.ibm.ws.kernel.boot.nls_1.0.22.jar] from classloader hierarchy
C:\lang\appserver\wlp\wlp18\lib\com.ibm.ws.kernel.boot.nls_1.0.22.jar (File not found)

Thank you

4 Answers

You can look into a sample Spring Boot war application in https://github.com/anjumfatima90/dojo.samples. It has the steps to deploy on liberty. I hope this helps.

UPDATE: There are two ways to deploy a spring boot war in open-liberty, you were deploying it as a plain old WAR which does not require adding springBoot-2.0 feature to the server.xml. My github sample shows another way where you can add springBoot-2.0 feature in your server.xml along with changes in the <application> tag as in https://www.ibm.com/support/knowledgecenter/SSEQTP_liberty/com.ibm.websphere.wlp.doc/ae/twlp_dep_springboot.html

Considering your way, which is deploying as a plain old WAR. Scott has cloned your application and made some changes to add liberty-maven-plugin in his repo https://github.com/scottkurz/springboot-liberty-1 to help you with this.

Steps to work:

  1. Clone repository using git clone https://github.com/scottkurz/springboot-liberty-1.git.
  2. Run mvn clean install
  3. Run mvn liberty:run
  4. You will find a liberty folder created in the target folder of the application. You can compare your server with target/liberty/wlp/usr/servers/defaultServer.

NOTE: Scott added alerts.properties in src/main/resources of application.

If you are packaging the application as a true war and not a converted jar file, then all you need is the servlet feature and dropins folder.

My server.xml:

<server description="Tester">
    <featureManager>
        <feature>servlet-4.0</feature>
    </featureManager>

    <httpEndpoint host="*" httpPort="9080" httpsPort="9443" id="defaultHttpEndpoint"/>
</server>

pom.xml:

<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.ibm.example</groupId>
    <artifactId>SpringbootWeb</artifactId>
    <packaging>war</packaging>
    <version>1.0.0</version>

    <parent>
        <groupId>io.openliberty.tools</groupId>
        <artifactId>liberty-maven-app-parent</artifactId>
        <version>3.2</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <packaging.type>minify,runnable</packaging.type>
    </properties>

    <profiles>
        <profile>
            <id>usr-package</id>
            <properties>
                <packaging.type>usr</packaging.type>
            </properties>
        </profile>
    </profiles>


    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                    <packagingExcludes>pom.xml</packagingExcludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>io.openliberty.tools</groupId>
                <artifactId>liberty-maven-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <assemblyArtifact>
                        <groupId>io.openliberty</groupId>
                        <artifactId>openliberty-runtime</artifactId>
                        <version>[18.0.0.1,)</version>
                        <type>zip</type>
                    </assemblyArtifact>
                    <serverName>${project.artifactId}Server</serverName>
                    <include>${packaging.type}</include>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>2.19.1</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.2.5.RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

When you run the package goal in Maven it will create a war and a jar that contains the liberty runtime package for you in jar format. You can take the war and place it in your dropins folder of your current application. Make sure there are no other errors in the Liberty messages.log file.

My example on GitHub -Brian

Finally it works, I started with a new project. Here the pom.xml (with liberty-maven-plugin):

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <groupId>it.mycompany</groupId>
    <artifactId>alerts</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <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>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>com.ibm.mq</groupId>
            <artifactId>com.ibm.mq.allclient</artifactId>
            <version>9.1.4.0</version>
        </dependency>
    </dependencies>

    <packaging>war</packaging>

    <build>
        <finalName>${artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>io.openliberty.tools</groupId>
                <artifactId>liberty-maven-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <appsDirectory>apps</appsDirectory>
                    <mainClass>${start-class}</mainClass>
                </configuration>
            </plugin> 
        </plugins>
    </build>
</project>

The entry point class:

@SpringBootApplication
@PropertySource("classpath:alerts.properties")
public class WebApplication extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(WebApplication.class);
    }
}

I created the WAR with mvn clean install then I copied it from the target dir to wlp/servers/myserver/apps (not dropins)

Finally I set the server.xml as the following:

<server description="Tester">
    <featureManager>
        <feature>servlet-4.0</feature>
        <feature>localConnector-1.0</feature>
        <feature>jsp-2.3</feature>
        <feature>springBoot-2.0</feature>
    </featureManager>

    <httpEndpoint host="*" httpPort="9080" httpsPort="9443"
        id="defaultHttpEndpoint" />

    <library>
        <file id="alerts.properties"
            name="${shared.resource.dir}/alerts.properties" />
    </library>
    <webApplication id="alerts" location="alerts.war"
        name="alerts" contextRoot="/" />
</server>

The Liberty Server starts fine, the application works, the only problem is that responds to localhost:9080/login and not to localhost:9080/alerts/login. However the goal of the question is achieved, I've created a war file and it runs on a Liberty Server.

Thanks to all and especially thanks to @ScottKurz and @Anjum Fatima.

Related