記一次將spring-boot應用發佈到weblogic的步驟以及遇到的問題

說明

環境
linux:Red Hat 4.8.3-9
weblogic:weblogic 12.1.3
JDK:JDK1.8

程序環境
構建構建:Apache Maven 3.6.1
框架:ijcf 3.2.0(啊,使我們公司的一個內部框架,你可以理解爲Spring、Spring-boot、Spring-web、Spring-MVC等對Spring開源框架的二次封裝)

應用程序本身是一個後臺java應用程序,用戶要求必須運行在weblogic中。故將應用改造成web應用程序。

應用發佈到weblogic的步驟

第一步:在應用的src/main新建webapp,新建web.xml和weblogic.xml。

  1. web.xml代碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>com.sitech.crmmci.lsms2.app.SpringBootWebLogicApplication</param-value>
    </context-param>

    <listener>
<!--
        <listener-class>org.springframework.boot.legacy.context.web.SpringBootContextLoaderListener</listener-class>
-->
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <filter>
        <filter-name>metricFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>metricFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextAttribute</param-name>
            <param-value>org.springframework.web.context.WebApplicationContext.ROOT</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

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

</web-app>
  1. weblogic代碼如下:
<?xml version='1.0' encoding='UTF-8'?>
<weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.3/weblogic-web-app.xsd">


    <context-root>/spring-boot-weblogic-app</context-root>
    <container-descriptor>
        <optimistic-serialization>true</optimistic-serialization>
        <prefer-web-inf-classes>false</prefer-web-inf-classes>
        <show-archived-real-path-enabled>true</show-archived-real-path-enabled>
        <prefer-application-packages>
            <package-name>org.slf4j</package-name>
            <package-name>javax.validation.*</package-name>
            <package-name>org.hibernate.*</package-name>
            <package-name>javax.el.*</package-name>
            <package-name>org.springframework.*</package-name>
            <package-name>org.springframework.web.*</package-name>
            <package-name>org.springframework.boot.*</package-name>
            <package-name>org.springframework.boot.legacy*</package-name>
            <package-name>com.google.*</package-name>
        </prefer-application-packages>
    </container-descriptor>

</weblogic-web-app>

第二步:配置pom文

  1. packaing元素的修改爲war
<packaging>war</packaging>
  1. 在pom中添加maven-war-plugin和spring-boot-maven-plugin插件,用於在執行mvn package默認執行者兩個插件的目標。
<build>
<plugins>
	<plugin>
		<groupId>org.apache.maven.plugins</groupId>
		<artifactId>maven-war-plugin</artifactId>
		<configuration>
			<attachClasses>true</attachClasses>
			<archive>
				<manifestEntries>
					<Weblogic-Application-Version>${project.version}</Weblogic-Application-Version>
				</manifestEntries>
				<manifest>
					<addClasspath>true</addClasspath>
					<addClasspath>lib/</addClasspath>
				</manifest>
			</archive>
			<webResources>
				<resource>
					<directory>${project.basedir}/src/main/webapp</directory>
				</resource>
			</webResources>
			<warName>${project.artifactId}</warName>
		</configuration>
	</plugin>

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

第三步: 添加啓動類

package com.sitech.crmmci.lsms2.app;

import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.WebApplicationInitializer;

/**
 * @author zhangxy
 * @credte 2019-06-26 9:00
 */
@SpringBootApplication
@EnableAutoConfiguration
@Configuration
@ComponentScan
public class SpringBootWebLogicApplication extends SpringBootServletInitializer implements WebApplicationInitializer {

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

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(SpringBootWebLogicApplication.class).bannerMode(Banner.Mode.OFF);//.showBanner(false);
    }
}

第四步:執行mvn clean package命令打成war上傳服務器,使用weblogic控制檯部署此war。

部署遇到的問題

本來通過在啓動類上添加@SpringBootApplication,運行在使用Maven的tomcat插件中是一點問題都沒有,但是將程序改造成web應用,達成war部署到weblogic中出現了各種問題。
不要問我這些問題的底層原理?我TM也很惆悵,事情搞完了後不知其然,也不知其所然,好TM自閉。
第一個錯誤:
<Jun 27, 2019 2:33:18 PM CST> <Error> <Munger> <BEA-2156200> <Unable to load descriptor weblogic.utils.classloaders.GenericClassLoader@5f0a0470 finder: weblogic.utils.classloaders.CodeGenClassFinder@24fe96fa annotation: /WEB-INF/lib/tomcat-embed-websocket-9.0.14.jar!/META-INF/web-fragment.xml of module lsms2-app-0.0.1-SNAPSHOT-BOOT. The error is weblogic.descriptor.DescriptorException: Unmarshaller failed
**原因:**沒有導入tomcat-embed-websocket-9.0.14.jar
解決方案:
在pom中添加依賴

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

Maven會根據傳遞性依賴間接導入tomcat-embed-websocket jar。依賴關係如圖:
在這裏插入圖片描述
——————————————————————————————————
第二個問題:
java.lang.NoSuchMethodError: javax.validation.Configuration.getDefaultParameterNameProvider()Ljavax/validation/ParameterNameProvider;
原因: javax/validation/ParameterNameProvider是validation-api-2.0.0.Final.jar中的類。weblogic應該也自帶validation-api包,所有衝突了。
解決方案: 在weblogic.xml添加如下配置表示優先使用應用中的jar。

<package-name>javax.validation.*</package-name>
validation-api-2.0.0.Final.jar也通過Maven傳遞性依賴引出的。如果你沒有用ijcf框架,可以顯示在pom中制定對此java的依賴。
在這裏插入圖片描述
——————————————————————————————————
第三個問題:

java.lang.IllegalAccessError: tried to access class javax.el.ELUtil from class javax.el.ELManager tried to access class javax.el.ELUtil from class javax.el.ELManager
原因: javax.el.ELManager在javax.el-api-3.0.0.jar中,應用依賴的javax.el-api-3.0.0.ja與web中自帶的javax.el-api衝突。
解決方案: 在weblogic.xml添加如下配置表示優先使用應用中的jar。

<package-name>javax.el.*</package-name>

——————————————————————————————————

第四個問題:
[J2EE:160144]Failed to register library Extension-Name: lsms2-app, Implementation-Version: 0.0.1: Library cannot have Implementation-Version set, without also specifying its Specification-Version
**原因:**部署的時候選擇錯誤。
**解決方案:**在weblogic控制檯部署時選擇如圖中的選項即可解決。
在這裏插入圖片描述
——————————————————————————————————
第五個問題:

<Jun 27, 2019 5:09:35 PM CST> <Warning> <HTTP> <BEA-101162> <User defined listener org.springframework.boot.legacy.context.web.SpringBootContextLoaderListener failed: java.lang.NoSuchMethodError: org.springframework.boot.builder.SpringApplicationBuilder.<init>([Ljava/lang/Object;)V. java.lang.NoSuchMethodError: org.springframework.boot.builder.SpringApplicationBuilder.<init>([Ljava/lang/Object;)V
原因: org.springframework.boot.legacy.context.web.SpringBootContextLoaderListener在spring-boot-legacy-2.0.0.RELEASE.jar中,缺少此包。
解決方案: 在pom只添加對此包的依賴

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-legacy</artifactId> <version>2.0.0.RELEASE</version> </dependency>

——————————————————————————————————
第六個問題:

java.lang.IllegalStateException: No WebApplicationContext found: initializer not registered? No WebApplicationContext found: initializer not registered?
原因::web.xml中的listener.listener-class沒有配置或配置不正確。
解決方案: 在web.xml中添加正確的監聽。我的項目一開始使用了SpringBootContextLoaderListener監聽類,後來改成ContextLoaderListener就不報這個錯誤了。

    <listener>
<!-- 
        <listener-class>org.springframework.boot.legacy.context.web.SpringBootContextLoaderListener</listener-class>
-->
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

——————————————————————————————————
總結一下無非是兩類錯誤:一類是缺少jar,另一類是jar衝突。前者看缺少的那個類在那個jar中(可能在高版本的jar中,不在低版本的jar中),導入對應的jar即可。後者在weblogic.xml中添加相關的配置,來表明優先使用應用中jar即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章