springbootlearner
springbootlearner

Reputation: 1390

Liberty profile not able to detect Spring Boot componentscan annotation and not loading application context

I am deploying Spring Boot web application in Liberty 16.0.0.3.Have provided all dependency scope as provided and configured global shared library.But when I start the application Liberty not been able to load application context.

My configuration as below.

My pom.xml

<?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>com.myapp.testapp</groupId>
    <artifactId>testsharedlib</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>testsharedlib</name>
    <description>Demo project for Spring Boot</description>

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

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <runtime.scope>provided</runtime.scope>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <scope>${runtime.scope}</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-ws</artifactId>
            <scope>${runtime.scope}</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>



    <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <!-- <version>2.3</version> -->
            <executions>
               <execution>
                  <goals>
                     <goal>repackage</goal>
                  </goals>
                  <configuration>
                     <skip>true</skip>
                     <!-- <failOnMissingWebXml>false</failOnMissingWebXml> -->
                  </configuration>
               </execution>
            </executions>
         </plugin>
         <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                    <packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
                    <archive>
                        <manifest>
                            <mainClass>com.myapp.testapp.Appconfig</mainClass>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                        </manifest>
                        <manifestEntries>
                            <DisableIBMJAXWSEngine>true</DisableIBMJAXWSEngine>
                            <Class-Path>conf</Class-Path>
                        </manifestEntries>
                    </archive>
                </configuration>
            </plugin>

         <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>

         <plugin>
            <artifactId>maven-resources-plugin</artifactId>
         </plugin>
      </plugins>
   </build>


</project>

Liberty server.xml

<server description="Default Server">

    <featureManager>
    <feature>webProfile-7.0</feature>
        <feature>localConnector-1.0</feature>
    </featureManager>


   <library id="global">
        <fileset dir="${server.config.dir}/lib/jars" includes="*.jar"/>
    </library>

    <application context-root="HelloWorld" location="text-1.0.0-SNAPSHOT.war">
        <classloader commonLibraryRef="global" delegation="parentFirst"/>
    </application>

   <!-- Define the host name for use by the collective.
        If the host name needs to be changed, the server should be
        removed from the collective and re-joined. -->
   <variable name="defaultHostName" value="localhost"/>

   <keyStore id="defaultKeyStore" password="adminpwd"/>

    <!-- Define an Administrator and non-Administrator -->
   <basicRegistry id="basic">
      <user name="admin" password="adminpwd"/>
      <user name="nonadmin" password="nonadminpwd"/>
   </basicRegistry>

   <!-- Assign 'admin' to Administrator -->
   <administrator-role>
      <user>admin</user>
   </administrator-role>

   <webContainer deferServletLoad="false"/>
   <applicationManager autoExpand="true"/>

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

    <logging consoleLogLevel="INFO" traceSpecification="*=info:com.ibm.ws.classloading.*=ALL"/>


</server>

Upvotes: 2

Views: 2121

Answers (2)

springbootlearner
springbootlearner

Reputation: 1390

I am able to make it work by providing WEB-INF/web.xml in Liberty with global shared Library. Find below sample configuration.

pom.xml

<?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>com.myapp.testapp</groupId>
    <artifactId>testsharedlib</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>testsharedlib</name>
    <description>Demo project for Spring Boot</description>

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

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <runtime.scope>provided</runtime.scope>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <scope>${runtime.scope}</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-ws</artifactId>
            <scope>${runtime.scope}</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
<build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
               <execution>
                  <goals>
                     <goal>repackage</goal>
                  </goals>
                  <configuration>
                     <skip>true</skip>
                  </configuration>
               </execution>
            </executions>
         </plugin>

         <plugin>
            <artifactId>maven-resources-plugin</artifactId>
         </plugin>
      </plugins>
   </build>
</project>

server.xml

    <featureManager>
    <feature>webProfile-7.0</feature>
        <feature>localConnector-1.0</feature>
    </featureManager>


   <library id="global">
        <fileset dir="${server.config.dir}/lib/jars" includes="*.jar"/>
    </library>

    <application context-root="HelloWorld" location="text-1.0.0-SNAPSHOT.war">
        <classloader commonLibraryRef="global" delegation="parentLast"/>
    </application>

   <!-- Define the host name for use by the collective.
        If the host name needs to be changed, the server should be
        removed from the collective and re-joined. -->
   <variable name="defaultHostName" value="localhost"/>

   <keyStore id="defaultKeyStore" password="adminpwd"/>

    <!-- Define an Administrator and non-Administrator -->
   <basicRegistry id="basic">
      <user name="admin" password="adminpwd"/>
      <user name="nonadmin" password="nonadminpwd"/>
   </basicRegistry>

   <!-- Assign 'admin' to Administrator -->
   <administrator-role>
      <user>admin</user>
   </administrator-role>

   <webContainer deferServletLoad="false"/>
   <applicationManager autoExpand="true"/>

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

    <logging consoleLogLevel="INFO" traceSpecification="*=info:com.ibm.ws.classloading.*=ALL"/>

</server>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">

 <display-name>pctext</display-name>

 <servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
            <param-name>contextClass</param-name>
            <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
        </init-param>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>com.myapp.testpkg.ApplicationConfig</param-value>
        </init-param>
    <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
 </servlet-mapping>

</web-app>

ApplicationConfig.java

@SpringBootApplication(scanBasePackages={"com.myapp.testpkg"})

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

Upvotes: 1

Andy Guibert
Andy Guibert

Reputation: 42966

The reason why this works with dependencies in WEB-INF/lib and not in a global shared lib is because the servlet that initializes your Spring application (org.springframework.web.servlet.DispatcherServlet) is coming from one of the jar dependencies. Liberty will only scan the web context root (i.e. WEB-INF/*) for servlet classes. It will not scan shared libraries for servlet classes.

As you found out in your other answer, the only way to link up a servlet coming from a jar in a shared lib is to explicitly declare it in web.xml (since Liberty will not auto-scan for it like it does for classes or jars in WEB-INF/*.

To confirm this, I wrote a simple servlet:

@WebServlet("/LibServlet")
public class LibServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException 
    {
        response.getWriter().append("Served at: ").append(request.getContextPath());
    }
}

Then I packaged this servlet into servletLib.jar. When I provided this lib to my application using a shared library, I was not able to access the servlet at http://localhost:9080/testapp/LibServlet. However, when I moved servletLib.jar into a WEB-INF/lib then the servlet was accessible.

Upvotes: 1

Related Questions