削减成本:如何将EAR转换为胖OSGi Bundle并部署到Equinox容器?
从EAR到Equinox胖OSGi Bundle:实操思路分享
我之前刚好处理过类似的开发环境迁移需求,给你梳理几个落地性强的步骤,应该能帮你搞定这件事:
第一步:先拆解并清理EAR内容
首先把你的EAR解压,先理清楚里面的结构:一般会有WAR包、EJB JAR包、lib/目录下的第三方依赖,还有WebSphere专属的部署描述符(比如ibm-web-bnd.xml这类)。
- 先把WebSphere特有的依赖和配置删掉,比如
com.ibm.*开头的非通用JAR,这些Equinox完全不需要,开发环境只要保证业务逻辑能跑就行。 - 如果你的代码里硬编码了WebSphere的API(比如
com.ibm.websphere.servlet.*),得换成标准Java EE API替代,比如用普通的javax.servlet接口就行。
第二步:合并资源并生成OSGi Bundle Manifest
这是核心步骤,OSGi Bundle必须有MANIFEST.MF来声明依赖、包导出/导入等信息,这里推荐用bnd工具来简化操作(比手动写Manifest靠谱多了):
- 先把WAR里的
WEB-INF/classes、EJB JAR里的所有类、lib/下的非WebSphere依赖JAR里的类,都合并到同一个目录(比如target/merged-classes)。 - 写一个
bnd.bnd配置文件,示例如下:Bundle-Name: 你的应用胖Bundle Bundle-SymbolicName: com.yourcompany.yourapp.fatbundle Bundle-Version: 1.0.0 # 如果你需要启动时执行初始化逻辑,就加Activator,不需要可以删掉 Bundle-Activator: com.yourcompany.yourapp.AppActivator # 自动导入所有依赖的包,Equinox会自动找对应的bundle提供这些包 Import-Package: * # 导出你需要对外暴露的业务包,不需要的话可以不写 Export-Package: com.yourcompany.yourapp.* # 把WAR里的静态资源、WEB-INF配置也打包进去 Include-Resource: WEB-INF/, static/ - 然后用bnd命令打包:
bnd wrap -output yourapp-fatbundle.jar target/merged-classes/,这样就生成了一个符合OSGi规范的胖Bundle。
第三步:适配Web应用和EJB到Equinox环境
Equinox不是Java EE容器,所以得做一些适配,开发环境不用太复杂:
- Web应用适配:
用Equinox的Http Service来注册Servlet/JSP,两种方式可选:- 写一个Bundle Activator手动注册:
public class AppActivator implements BundleActivator { private ServiceRegistration<Servlet> mainServletReg; @Override public void start(BundleContext context) throws Exception { // 设置Servlet的访问路径 Dictionary<String, String> props = new Hashtable<>(); props.put("alias", "/yourapp"); // 注册你的主Servlet mainServletReg = context.registerService(Servlet.class, new YourMainServlet(), props); } @Override public void stop(BundleContext context) throws Exception { if (mainServletReg != null) { mainServletReg.unregister(); } } } - 用Declarative Services(DS),不需要写Activator,直接用注解声明Servlet,更简洁。
- 写一个Bundle Activator手动注册:
- EJB适配:
开发环境里完全可以把EJB当成普通Java类来用:- 如果是无状态会话Bean这类简单的,直接去掉
@Stateless这类注解,代码里直接实例化调用就行。 - 如果用到了EJB的依赖注入,可以用轻量级框架(比如Guice或者Spring DM)来替代,在Equinox里跑完全没问题。
- 如果是无状态会话Bean这类简单的,直接去掉
第四步:部署测试到Equinox
- 先下载Equinox核心包(直接用Eclipse提供的
org.eclipse.osgiJAR就行)。 - 把你的胖Bundle放到Equinox的
dropins目录,然后启动Equinox:java -jar org.eclipse.osgi_*.jar -console - 在控制台里用
ss命令看bundle状态:如果是ACTIVE就说明启动成功;如果是RESOLVED/INSTALLED,用diag <bundle-id>命令查依赖缺失,然后把对应的依赖bundle(比如javax.servlet的bundle)放到dropins里就行。 - 要是Web应用,启动后访问
http://localhost:8080/yourapp就能测试了,端口可以用启动参数改:-Dorg.osgi.service.http.port=8081。
几个避坑小贴士
- 别把Java EE API(比如javax.servlet、javax.ejb)塞进胖Bundle里,直接用Equinox自带的系统bundle或者专门的API bundle,不然会和Equinox的类加载器冲突。
- 如果代码里用到了JNDI,用Equinox的
org.eclipse.equinox.jndi提供轻量级JNDI服务,或者直接改成硬编码获取资源(开发环境嘛,怎么方便怎么来)。 - 不用追求和WebSphere完全一致,这个环境只给开发者用,只要保证业务逻辑能跑、能调试就够了。
内容的提问来源于stack exchange,提问作者Arun Raja
相关产品推荐
相关产品推荐

