我正在尝试了解 Struts2 OSGi 插件是如何工作的,因此我首先尝试部署此博客文章提供的测试应用程序。我已从 WEB-INF/classes/bundles/2 文件夹中删除所有捆绑包,并尝试一次添加一个,以便更好地解决我的问题。我面临的问题如下:
(1) 当我尝试包含 MyOsgi.jar 包(它是一个空包,只包含一个实现 BundleActivator 的类)时,我在应用程序部署期间收到以下错误:
| 在 org.apache.felix.framework.Felix.createBundleActivator(Felix.java:3548)|#] [#|2013-01-07T18:32:14.513+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std .com.sun.enterprise.server.logging|_ThreadID=105;_ThreadName=Thread-2;| 在 org.apache.felix.framework.Felix._startBundle(Felix.java:1666)|#] [#|2013-01-07T18:32:14.513+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std .com.sun.enterprise.server.logging|_ThreadID=105;_ThreadName=Thread-2;| 在 org.apache.felix.framework.Felix.startBundle(Felix.java:1588)|#] [#|2013-01-07T18:32:14.513+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std .com.sun.enterprise.server.logging|_ThreadID=105;_ThreadName=Thread-2;| 在 org.apache.felix.framework.Felix.setFrameworkStartLevel(Felix.java:1180)|#] 3548)|#] [#|2013-01-07T18:32:14.513+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=105;_ThreadName=线程 2;| 在 org.apache.felix.framework.Felix._startBundle(Felix.java:1666)|#] [#|2013-01-07T18:32:14.513+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std .com.sun.enterprise.server.logging|_ThreadID=105;_ThreadName=Thread-2;| 在 org.apache.felix.framework.Felix.startBundle(Felix.java:1588)|#] [#|2013-01-07T18:32:14.513+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std .com.sun.enterprise.server.logging|_ThreadID=105;_ThreadName=Thread-2;| 在 org.apache.felix.framework.Felix.setFrameworkStartLevel(Felix.java:1180)|#] 3548)|#] [#|2013-01-07T18:32:14.513+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=105;_ThreadName=线程 2;| 在 org.apache.felix.framework.Felix._startBundle(Felix.java:1666)|#] [#|2013-01-07T18:32:14.513+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std .com.sun.enterprise.server.logging|_ThreadID=105;_ThreadName=Thread-2;| 在 org.apache.felix.framework.Felix.startBundle(Felix.java:1588)|#] [#|2013-01-07T18:32:14.513+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std .com.sun.enterprise.server.logging|_ThreadID=105;_ThreadName=Thread-2;| 在 org.apache.felix.framework.Felix.setFrameworkStartLevel(Felix.java:1180)|#] felix.framework.Felix._startBundle(Felix.java:1666)|#] [#|2013-01-07T18:32:14.513+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.企业.server.logging|_ThreadID=105;_ThreadName=Thread-2;| 在 org.apache.felix.framework.Felix.startBundle(Felix.java:1588)|#] [#|2013-01-07T18:32:14.513+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std .com.sun.enterprise.server.logging|_ThreadID=105;_ThreadName=Thread-2;| 在 org.apache.felix.framework.Felix.setFrameworkStartLevel(Felix.java:1180)|#] felix.framework.Felix._startBundle(Felix.java:1666)|#] [#|2013-01-07T18:32:14.513+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.企业.server.logging|_ThreadID=105;_ThreadName=Thread-2;| 在 org.apache.felix.framework.Felix.startBundle(Felix.java:1588)|#] [#|2013-01-07T18:32:14.513+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std .com.sun.enterprise.server.logging|_ThreadID=105;_ThreadName=Thread-2;| 在 org.apache.felix.framework.Felix.setFrameworkStartLevel(Felix.java:1180)|#] enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=105;_ThreadName=Thread-2;| 在 org.apache.felix.framework.Felix.setFrameworkStartLevel(Felix.java:1180)|#] enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=105;_ThreadName=Thread-2;| 在 org.apache.felix.framework.Felix.setFrameworkStartLevel(Felix.java:1180)|#]
[#|2013-01-07T18:32:14.514+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=105;_ThreadName=Thread-2;| 在 org.apache.felix.framework.StartLevelImpl.run(StartLevelImpl.java:265)|#]
[#|2013-01-07T18:32:14.514+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.std .com.sun.enterprise.server.logging|_ThreadID=105;_ThreadName=Thread-2;| 在 java.lang.Thread.run(Thread.java:722)|#]
据此,上述错误是由于在 JVM 中加载了多个 BundleActivator 类,这是有道理的,因为包含它的 felix.jar 已经在 GlassFish 中可用,并且我的应用程序中包含了许多 felix jar作为 Struts2 OSGi 插件的依赖项。我尝试从插件中排除 felix 依赖项(我正在使用 Maven 构建应用程序),但这不起作用,因为作为依赖项包含的 felix jar 还包括 felix.jar 中不存在的其他类。
(2) 当我尝试包含 struts2-osgi-demo-bundle-2.3.1 包时,我得到一个完全不同的错误,我不知道可能是什么原因:
[#|2013-01-07T18:30:02.897+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.container.web.com.sun.enterprise.web|_ThreadID=42;_ThreadName=Thread-2;| WebModule[/osgi]PWC1270:异常启动过滤器struts2 java.lang.LinkageError:加载程序约束违规:加载程序(org/apache/felix/framework/searchpolicy/ContentClassLoader 的实例)先前启动了名称为“org/osgi”的不同类型的加载/framework/BundleContext”在 java.lang.Class.privateGetDeclaredMethods(Class.java:2442) 在 java.lang.Class.privateGetPublicMethods(Class.java:2562) 在 java.lang.Class.getDeclaredMethods0(Native Method) 在 java。 org.apache.struts2.convention.PackageBasedActionConfigBuilder.getActionAnnotations(PackageBasedActionConfigBuilder.java:792) 中的 org.apache.struts2 中的 lang.Class.getMethods(Class.java:1427)。org.apache.struts2.convention.PackageBasedActionConfigBuilder.buildActionConfigs(PackageBasedActionConfigBuilder.java:335) org.apache.struts2.convention.ClasspathPackageProvider.loadPackages(ClasspathPackageProvider.java:53) 中的约定.PackageBasedActionConfigBuilder.buildConfiguration(PackageBasedActionConfigBuilder.java:605)在 org.apache.struts2.osgi.OsgiConfigurationProvider.loadConfigFromBundle(OsgiConfigurationProvider.java:146) 在 org.apache.struts2.osgi.OsgiConfigurationProvider.loadPackages(OsgiConfigurationProvider.java:96) 在 com.opensymphony.xwork2.config.impl.DefaultConfiguration .reloadContainer(DefaultConfiguration.java:215) 在 com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:66) 在 org.apache.struts2.dispatcher.Dispatcher。init_PreloadConfiguration(Dispatcher.java:390) at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:436) at org.apache.struts2.dispatcher.ng.InitOperations.initDispatcher(InitOperations.java:69) at org .apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.init(StrutsPrepareAndExecuteFilter.java:51) 在 org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:264) 在 org.apache.catalina.core.ApplicationFilterConfig .(ApplicationFilterConfig.java:120) 在 org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4685) 在 org.apache.catalina.core.StandardContext.start(StandardContext.java:5377) 在 com.sun .enterprise.web.WebModule.start(WebModule.java:498) 在 org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:917) 在 org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:901) 在 org.apache.catalina.core.StandardHost.addChild(StandardHost.java:733) 在 com.sun.enterprise.web.WebContainer .loadWebModule(WebContainer.java:2019) at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1669) at com.sun.enterprise.web.WebApplication.start(WebApplication.java:109) at org. glassfish.internal.data.EngineRef.start(EngineRef.java:130) at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:269) at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo. java:301) 在 com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:461) 在 com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240) 在 org.glassfish .deployment.admin.DeployCommand.execute(DeployCommand.java:389) 在 com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:348) 在 com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand (CommandRunnerImpl.java:363) at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1085) at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:95)在 com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1291) 在 com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1259) 在 com.sun .enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:461) 在 com.sun.enterprise.v3.admin.AdminAdapter.service(AdminAdapter.java:212) 在 com.sun.grizzly.tcp.http11。GrizzlyAdapter.service(GrizzlyAdapter.java:179) at com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:117) at com.sun.enterprise.v3.services.impl.ContainerMapper$Hk2DispatcherCallable.call( ContainerMapper.java:354) 在 com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195) 在 com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860) 在 com .sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757) 在 com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056) 在 com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter .java:229) 在 com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) 在 com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) 在 com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90) 在 com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) 在 com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask .java:54) 在 com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) 在 com.sun.grizzly.ContextTask.run(ContextTask.java:71) 在 com.sun.grizzly.util.AbstractThreadPool$ Worker.doWork(AbstractThreadPool.java:532) at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) at java.lang.Thread.run(Thread.java:722) |#]doCall(ProtocolChainContextTask.java:54) at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) at com.sun.grizzly.ContextTask.run(ContextTask.java:71) at com.sun.grizzly.util .AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) at java.lang.Thread.run(Thread.java:722) | #]doCall(ProtocolChainContextTask.java:54) at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) at com.sun.grizzly.ContextTask.run(ContextTask.java:71) at com.sun.grizzly.util .AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) at java.lang.Thread.run(Thread.java:722) | #]
我注意到 struts2-osgi-demo-bundle-2.3.1 捆绑包没有 BundleActivator 类,我猜这是我没有收到上一个错误的原因,但这并不能帮助我找到解决方案.
最后,我可以在 Tomcat 中毫无问题地部署包含这两个包的应用程序,这使我得出结论,这两个问题都与 GlassFish 的 felix.jar 的存在有关。
有没有人在 GlassFish 中使用过 Struts2 OSGi 插件,或者您知道如何克服这些问题吗?
更新:上面的第二个错误是由于捆绑包中包含的 BundlesAction 类而发生的,该类实现了 BundleContextAware。根据插件的文档,插件定义了 OSGi 拦截器,它
将检查动作,如果它实现了 org.apache.struts2.osgi.interceptor.BundleContextAware,它将在动作上调用 setBundleContext(BundleContext bundleContext),传递 OSGi 容器的 BundleContext。
我猜这是问题开始的地方。
更新 2:正如 Lukasz 和 Tang 所建议的,插件需要更新才能使用更新的 Felix 版本,并且(可能)使用 GlassFish 已经可用的 OSGi 运行时,而不是启动新的运行时。对此,我有以下问题:
- 是否可以在同一个应用程序服务器中有两个 OSGi 运行时,即。插件可以忽略服务器的 OSGi 运行时并启动它自己的(当然假设它已更新为使用与 GlassFish 相同的 Felix 版本,以免类路径中有多个版本的 Felix 类)?
- 为了使用 GlassFish 的 OSGi 运行时,插件需要获取对它的引用。这可以在未部署为 OSGi 包的 Web 应用程序中完成吗?如果是,如何?