Liberty 配置文件无法检测到 Spring 引导组件扫描注释并且无法加载应用程序上下文

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

我正在部署 Spring 在 Liberty 16.0.0 中启动 Web 应用程序。3.Have 提供了所提供的所有依赖范围并在我启动应用程序 Liberty 时配置了全局共享 library.But能够加载应用程序上下文。

我的配置如下。

我的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>

自由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>

我可以通过在 Liberty 中提供 WEB-INF/web.xml 全局共享库来使其工作。在下面找到示例配置。

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);
  }
}

这与 WEB-INF/lib 中的依赖项而不是全局共享库中的依赖项一起工作的原因是因为初始化 Spring 应用程序 (org.springframework.web.servlet.DispatcherServlet) 的 servlet 来自以下之一jar 依赖项。 Liberty 将仅为 servlet 类 扫描 Web 上下文根(即 WEB-INF/*)。它不会扫描 servlet 类 的共享库。

正如您在其他答案中发现的那样,link 从共享库中的 jar 中获取 servlet 的唯一方法是在 web.xml 中显式声明它(因为 Liberty 不会像 类 或 WEB-INF/*.

中的罐子一样自动扫描它

为了证实这一点,我写了一个简单的 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());
    }
}

然后我把这个servlet打包成servletLib.jar。当我使用共享库向我的应用程序提供此库时,我无法访问 http://localhost:9080/testapp/LibServlet 处的 servlet。但是,当我将 servletLib.jar 移动到 WEB-INF/lib 时,servlet 就可以访问了。