weblogic修改banner_如何优雅的在weblogic上部署spring-boot

介绍

spring-boot应该是目前最火的java后台开发框架,现在java的简历里如果不贴个spring boo的标签都不好意思说自己是做java的,事实上现状就是如此,和当年ssh盛行时一模一样.不过说归说,spring-boot确实好用,学习成本低,入门快,开发效率高,自启动,天生适合容器化.但要把spring-boot部署到weblogic上,尤其是低版本的weblogic上,还是要费点功夫.如果要求高一点,优雅的部署,则要费点脑筋,这里说的优雅的部署,是指开发人员不需要因为服务器的限制对程序做特殊的配置,增加其学习成本和工作量.本文则探讨几种我认为优雅的方式,如看官有更好的方案,欢迎留言一起讨论.

实现

环境

ide

IntelliJ IDEA 2017.2

weblogic

10.3.6.0

weblogic-jdk

java version "1.8.0_171"

传统实现方案

1. 创建一个支持(Support)maven的工程

pom.xml

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

com.boostrdev.legacy.weblogic

spring-boot-legacy-weblogic

0.0.1-SNAPSHOT

war

Spring Boot Legacy WebLogic

Demo project for deploying a Spring Boot to a legacy (10.3.5) weblogic environment using servlet 2.5

4.2.5.RELEASE

1.1.12.RELEASE

org.springframework.boot

spring-boot-starter-parent

1.1.12.RELEASE

org.springframework.boot

spring-boot-legacy

1.0.2.RELEASE

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-tomcat

provided

javax.servlet

servlet-api

2.5

test

org.springframework.boot

spring-boot-starter-test

test

org.springframework

spring-web

${spring.version}

org.apache.maven.plugins

maven-war-plugin

true

${project.version}

true

lib/

${project.basedir}/src/main/resources/static

${project.basedir}/src/main/webapp

${project.artifactId}

org.springframework.boot

spring-boot-maven-plugin

${spring.boot.version}

BOOT

repackage

2. 创建spring boot入口类和测试接口

SpringBootWebLogicApplication.java

package com.yaya;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;

import org.springframework.boot.builder.SpringApplicationBuilder;

import org.springframework.boot.context.web.SpringBootServletInitializer;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.WebApplicationInitializer;

@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).showBanner(false);

}

}

TestService.java

package com.yaya;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.bind.annotation.RestController;

/**

* @Description:

* @author: jianfeng.zheng

* @since: 2018/7/20 上午9:58

* @history: 1.2018/7/20 created by jianfeng.zheng

*/

@RestController

public class TestService {

@RequestMapping("/welcome")

public String welcome(@RequestParam(name = "username") String username) {

return "welcome:" + username;

}

}

3. 创建web.xml 和 weblogic.xml

在IDEA里创建这两个文件方法如下:

File->Project-Structure->Project Settinngs->Facets

点击如图可以创建web.xml

点击Add Application Server specific...选择weblogic并指定版本创建weblogic.xml.(IDEA这个功能简直太贴心)

web.xml

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

contextConfigLocation

com.yaya.SpringBootWebLogicApplication

org.springframework.boot.legacy.context.web.SpringBootContextLoaderListener

metricFilter

org.springframework.web.filter.DelegatingFilterProxy

metricFilter

/*

appServlet

org.springframework.web.servlet.DispatcherServlet

contextAttribute

org.springframework.web.context.WebApplicationContext.ROOT

1

appServlet

/

weblogic.xml

xmlns:wls="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.4/weblogic-web-app.xsd">

/spring-boot-weblogic-app

org.slf4j.*

org.springframework.*

此时目录结构

.

├── SpringBootWeblogicDemo.iml

├── WEB-INF

│   ├── web.xml

│   └── weblogic.xml

├── pom.xml

└── src

├── main

│   ├── java

│   │   └── com

│   │   └── yaya

│   │   ├── SpringBootWebLogicApplication.java

│   │   └── TestService.java

│   ├── resources

│   │   └── static

│   └── webapp

└── test

└── java

4. 构建war包

选择菜单Build->BuildArtifacts->SpringBootWeblogicDemo:war->Build构建完的war包默认在target目录下spring-boot-weblogic.war

5. 部署war包

登录weblogic控制台选择Deployments->Install选择上面的war包部署.

6. 测试

curl http://10.1.11.118:7001/spring-boot-weblogic-app/welcome?username=jianfeng.zheng

welcome:jianfeng.zheng

存在的问题

如果你不嫌麻烦,那么到这里你已经把你的spring-boot部署到weblogic上,后面的内容可以不看.上面的方式虽然解决了问题,但也存在很多不足之处

配置项略多,增加学习成本(实际上不多,但新人动手能力令人发指)

因为入口类继承了SpringBootServletInitializer本地运行缺少Servlet环境,无法运行,调试起来麻烦(不知道怎么解决,如果知道欢迎评论留言)

理想的情况是,通过SPRING INITIALIZR生成spring-boot项目,开发完后通过某种手段可以实现快速部署weblogic的目的.接下来就探讨解决方案

脚本打包

基本思路是

本地开发提交工程到svn或者git

使用maven进行编译

将以上配置项和编译好到class文件一起重新打包

第3步详细讲下

可以将spring-boot-weblogic.war解压开看下目录结构

.

├── ./META-INF

│   └── ./META-INF/MANIFEST.MF

└── ./WEB-INF

├── ./WEB-INF/classes

│   └── ./WEB-INF/classes/com

│   └── ./WEB-INF/classes/com/yaya

│   ├── ./WEB-INF/classes/com/yaya/SpringBootWebLogicApplication.class

│   └── ./WEB-INF/classes/com/yaya/TestService.class

├── ./WEB-INF/lib

│   ├── ./WEB-INF/lib/spring-aop-4.2.5.RELEASE.jar

│   ├── ./WEB-INF/lib/spring-beans-4.2.5.RELEASE.jar

.....

├── ./WEB-INF/web.xml

└── ./WEB-INF/weblogic.xml

思路就是将以下文件和用户编译好的文件一起重新打包,并保持目录结构

SpringBootWebLogicApplication.class

/WEB/INF/lib/*.jar

web.xml

weblogic.xml

可以将这些文件从war包里解压出来放到指定目录下,这里称这个目录为pre-compiled-path

shell脚本如下:

spring-boot-war.sh

#!/bin/bash

#用户工程目录

v_s=$1

#脚本运行临时目录

v_d=$1/temp

#存放web.xml等文件目录

v_m=$2

rm -rf $v_d

mkdir -p $v_d

cp $v_s/pom.xml $v_d

cp -r $v_s/src $v_d

cd $v_d

#编译代码(跳过单元测试)

mvn compile -Dmaven.test.skip=true

mkdir -p $v_d/war

v_war=$v_d/war

cd $v_war

mkdir -p $v_war/WEB-INF

#拷贝编译好的class文件

cp -r $v_d/target/classes $v_war/WEB-INF/

#spring-boot入口类路径(可以写死)

v_app=$v_war/WEB-INF/classes/com/yaya/

mkdir -p $v_app

#拷贝入口类

cp $v_m/SpringBootWebLogicApplication.class $v_app

#拷贝web.xml和weblogic.xml

cp $v_m/web.xml $v_war/WEB-INF/

cp $v_m/weblogic.xml $v_war/WEB-INF/

#拷贝spring-boot依赖jar包

cp -r $v_m/lib $v_war/WEB-INF/lib

cd $v_war

#重新开始打包

jar -cvfM spring-boot-weblogic.war .

运行脚本,完成编译打包

./spring-boot.sh /you/spring-boot/source/path /you/pre-compiled/path

脚本运行成功后,在工程目录下,会创建一个temp目录,目标war包就在该目录下.

虽然完成了打包,并且也能成功部署到weblogic上运行但这个脚本目前context-root和war包名称都是写死的,我们需要一个能动态命名的脚本.解决的方案是,用sed命令对文本进行替换,名称由脚本参数指定.

修改weblogic.xml将wls:context-root用参数代替

xmlns:wls="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.4/weblogic-web-app.xsd">

/{app-name}

org.slf4j.*

org.springframework.*

修改脚本spring-boot-war.sh

#!/bin/bash

#用户工程目录

v_s=$1

#脚本运行临时目录

v_d=$1/temp

#存放web.xml等文件目录

v_m=$2

v_a=$3

rm -rf $v_d

mkdir -p $v_d

cp $v_s/pom.xml $v_d

cp -r $v_s/src $v_d

cd $v_d

#编译代码(跳过单元测试)

mvn compile -Dmaven.test.skip=true

mkdir -p $v_d/war

v_war=$v_d/war

cd $v_war

mkdir -p $v_war/WEB-INF

#拷贝编译好的class文件

cp -r $v_d/target/classes $v_war/WEB-INF/

#spring-boot入口类路径(可以写死)

v_app=$v_war/WEB-INF/classes/com/yaya/

mkdir -p $v_app

#拷贝入口类

cp $v_m/SpringBootWebLogicApplication.class $v_app

#拷贝web.xml和weblogic.xml

cp $v_m/web.xml $v_war/WEB-INF/

cp $v_m/weblogic.xml $v_war/WEB-INF/

#替换app-name

sed -i '' "s/{app-name}/${v_a}/g" $v_war/WEB-INF/weblogic.xml

#拷贝spring-boot依赖jar包

cp -r $v_m/lib $v_war/WEB-INF/lib

cd $v_war

#重新开始打包(文件名用变量替换)

jar -cvfM $v_a.war .

运行脚本

./spring-boot.sh /you/spring-boot/source/path /you/pre-compiled/path app-name

脚本会根据指定的app-name生成名称不同,context-root不同的war包.

自动部署

可以借助wlst.sh工具,将war包自动部署到weblogic上.因为要使用wlst.sh工具,所以服务器需要预先安装好weblogic.脚本使用jython语言编写.

deployApp.py

print '\n Begin deploy application'

try:

mUsername=sys.argv[1]

mPassword=sys.argv[2];

mConsoleURL=sys.argv[3];

mAppName=sys.argv[4];

mAppPath=sys.argv[5];

mTarget=sys.argv[6];

print('\n mServerName:')

print(mTarget)

print('\n appName:')

print(mAppName)

print('\n appPath:')

print(mAppPath)

connect(mUsername,mPassword,mConsoleURL)

progress=deploy(mAppName,mAppPath,targets=mTarget,upload='true',timeout=10000000)

dumpStack()

progress.printStatus()

except Exception, ex:

print ex.getMessage()

print '#########################################################'

print '##### Deploy Failed #########'

print '##### Contact support with Exception Stack #########'

print '#########################################################'

exit()

mUsername:console用户名

mPassword:console密码

mConsoleURL:console路径(带端口)

mAppName:app name

mAppPath:war包路径

mTarget:目标服务器,可以是server和集群名称

修改脚本spring-boot-war.sh

#!/bin/bash

#用户工程目录

v_s=$1

#脚本运行临时目录

v_d=$1/temp

#存放web.xml等文件目录

v_m=$2

#app-name

v_a=$3

#WLS_HOME weblogic安装目录

v_wls=$4

rm -rf $v_d

mkdir -p $v_d

cp $v_s/pom.xml $v_d

cp -r $v_s/src $v_d

cd $v_d

#编译代码(跳过单元测试)

mvn compile -Dmaven.test.skip=true

mkdir -p $v_d/war

v_war=$v_d/war

cd $v_war

mkdir -p $v_war/WEB-INF

#拷贝编译好的class文件

cp -r $v_d/target/classes $v_war/WEB-INF/

#spring-boot入口类路径(可以写死)

v_app=$v_war/WEB-INF/classes/com/yaya/

mkdir -p $v_app

#拷贝入口类

cp $v_m/SpringBootWebLogicApplication.class $v_app

#拷贝web.xml和weblogic.xml

cp $v_m/web.xml $v_war/WEB-INF/

cp $v_m/weblogic.xml $v_war/WEB-INF/

#替换app-name

sed -i '' "s/{app-name}/${v_a}/g" $v_war/WEB-INF/weblogic.xml

#拷贝spring-boot依赖jar包

cp -r $v_m/lib $v_war/WEB-INF/lib

cd $v_war

#重新开始打包(文件名用变量替换)

jar -cvfM $v_a.war .

#开始部署

$v_wls/common/bin/wlst.sh /script/path/deployApp.py weblogic admin-password admin-host:7001 $v_a $v_war/$v_a.war app_server

这样就可以将war包自动部署到weblogic上,实现整个过程自动化.

还有哪些需要做的

以上只是解决了部署过程中最核心的几个问题,但还有很多问题一定会碰到但未解决的:

怎么解决第三发依赖包的问题

如何做到版本管理,应用回滚

是否支持所有spring-boot特性

等等..

生产上的需求远远不是本地做个poc验证通过就可以解决的,但千里之行始于足下,走出第一步,就已经成功一半.

一些问题记录

编译jdk和weblogic 运行jdk需要1.8或以上版本

脚本在MacOS 10.12.4上运行通过,如果运行出错请自行根据操作系统版本做修改,一般是sed命令会跟操作系统版本有关.

运行spring-boot的weblogic server不要部署任何oracle 中间件产品,可能会有jar包冲突

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.boot.autoconfigure.web.ServerProperties org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration.properties; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'serverProperties' defined in class path resource [org/springframework/boot/autoconfigure/web/ServerPropertiesAutoConfiguration.class]: Initialization of bean failed; nested exception is java.lang.AbstractMethodError: org.apache.openjpa.persistence.PersistenceProviderImpl.getProviderUtil()Ljavax/persistence/spi/ProviderUtil;

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值