我试图了解Struts2 OSGi插件是如何工作的,所以我开始尝试部署this blog post提供的测试应用程序。我已从WEB-INF / classes / bundles / 2文件夹中删除了所有捆绑包,并尝试一次添加一个捆绑包,以便更好地解决我的问题。我面临的问题如下:
(1)当我尝试包含MyOsgi.jar包(它是一个只包含一个实现BundleActivator的类的空包)时,我在部署应用程序时遇到以下错误:
[#| 2013-01-07T18:32:14.425 + 0200 |严重| glassfish3.1.2 | javax.enterprise.system.std.com.sun.enterprise.server.logging | _ThreadID = 105; _ThreadName = Thread- 2; | java.lang.ClassCastException: myosgi.Activator无法强制转换为org.osgi.framework.BundleActivator 在org.apache.felix.framework.Felix.createBundleActivator(Felix.java:3548) 在org.apache.felix.framework.Felix._startBundle(Felix.java:1666) 在org.apache.felix.framework.Felix.startBundle(Felix.java:1588) 在org.apache.felix.framework.Felix.setFrameworkStartLevel(Felix.java:1180) 在org.apache.felix.framework.StartLevelImpl.run(StartLevelImpl.java:265) 在java.lang.Thread.run(Thread.java:722) |#] [#| 2013-01-07T18:32:14.513 + 0200 | SEVERE | glassfish3.1.2 | javax.enterprise.system.std.com.sun.enterprise.server.logging | _TreadID = 105; _TreadName = Thread- 2; |在 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 =线程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 =线程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 =线程2; |在 org.apache.felix.framework.Felix.setFrameworkStartLevel(Felix.java:1180)|#]
[#| 2013-01-07T18:32:14.514 + 0200 |严重| glassfish3.1.2 | javax.enterprise.system.std.com.sun.enterprise.server.logging | _ThreadID = 105; _ThreadName =线程2; |在 org.apache.felix.framework.StartLevelImpl.run(StartLevelImpl.java:265)|#]
[#| 2013-01-07T18:32:14.514 + 0200 |严重| glassfish3.1.2 | javax.enterprise.system.std.com.sun.enterprise.server.logging | _ThreadID = 105; _ThreadName =线程2; |在 java.lang.Thread.run(Thread.java:722)|#]
根据this,上述错误是由于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 |严重| glassfish3.1.2 | javax.enterprise.system.container.web.com.sun.enterprise.web | _ThreadID = 42; _ThreadName = Thread- 2; | WebModule [/ OSGi的] PWC1270: 异常启动过滤器struts2 java.lang.LinkageError:loader 约束违规:loader(实例) org / apache / felix / framework / searchpolicy / ContentClassLoader)之前 为名称不同的类型启动加载 "组织/ OSGi的/框架/的BundleContext"在 java.lang.Class.getDeclaredMethods0(Native Method)at java.lang.Class.privateGetDeclaredMethods(Class.java:2442)at at java.lang.Class.privateGetPublicMethods(Class.java:2562)at java.lang.Class.getMethods(Class.java:1427)at org.apache.struts2.convention.PackageBasedActionConfigBuilder.getActionAnnotations(PackageBasedActionConfigBuilder.java:792) 在 org.apache.struts2.convention.PackageBasedActionConfigBuilder.buildConfiguration(PackageBasedActionConfigBuilder.java:605) 在 org.apache.struts2.convention.PackageBasedActionConfigBuilder.buildActionConfigs(PackageBasedActionConfigBuilder.java:335) 在 org.apache.struts2.convention.ClasspathPackageProvider.loadPackages(ClasspathPackageProvider.java:53) 在 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)org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:436) 在 org.apache.struts2.dispatcher.ng.InitOperations.initDispatcher(InitOperations.java:69) 在 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)at 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) 在 com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1669) 在 com.sun.enterprise.web.WebApplication.start(WebApplication.java:109) 在org.glassfish.internal.data.EngineRef.start(EngineRef.java:130) 在org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:269) 在 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) 在 com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1085) 在 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) 在 com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:117) 在 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)at com.sun.grizzly.util.AbstractThreadPool $ Worker.doWork(AbstractThreadPool.java:532) 在 com.sun.grizzly.util.AbstractThreadPool $ Worker.run(AbstractThreadPool.java:513) 在java.lang.Thread.run(Thread.java:722)|#]
我注意到struts2-osgi-demo-bundle-2.3.1包没有BundleActivator类,我猜测这就是我没有得到上一个错误的原因,但是这并没有#&# 39;帮助我找到解决方案。
最后,我可以在Tomcat中部署包含两个捆绑包的应用程序而没有任何问题,这使我得出结论,这两个问题都与GlassFish的felix.jar的存在有关。
有没有人在GlassFish中使用过Struts2 OSGi插件,或者您是否知道如何克服这些问题?
UPDATE:上面的第二个错误是由于bundle中包含的BundlesAction类实现的,它实现了BundleContextAware。根据插件的文档,插件定义了OSGi拦截器,
将检查操作以及是否实现 org.apache.struts2.osgi.interceptor.BundleContextAware,它将调用 setBundleContext(BundleContext bundleContext)上的动作,传递 OSGi容器的BundleContext。
我猜是问题出在哪里。
更新2:由于Lukasz和Tang建议需要更新插件才能使用更新的Felix版本,并且(可能)使用GlassFish已经提供的OSGi运行时而不是启动新的一。对此,我有以下问题:
答案 0 :(得分:1)
我对struts不熟悉。根据我的看法[1],struts2-osgi插件负责两件事:
这两个功能都已内置在使用OSGi构建的GlassFish中。所以,我没有看到在GlassFish中运行基于osgi的struts2包时需要使用这个插件。因此,请尝试执行以下操作:
对于这两个操作,您需要使用GlassFish OSGi Admin界面。要了解有关它们的更多信息,请查看[2]。最简单的选择是将bundle复制到domain1 / autodeploy / bundles / dir,然后更新文件以查看它们在OSGi运行时中的更新。
希望这有帮助, Sahoo。
ps:请使用glassfish论坛来解决玻璃鱼问题。
答案 1 :(得分:1)
在Tang Yong的帮助下,我可以升级Struts2 OSGi插件,现在你可以将它与Glassfish 3一起使用。它应该很快就会作为Struts2版本2.3.15的一部分发布。
答案 2 :(得分:0)
您始终可以将Felix依赖项排除如下:
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-osgi-plugin</artifactId>
<version>2.3.1</version>
<exclusions>
<exclusion>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.main</artifactId>
<exclusion>
</exclusions>
</dependency>
答案 3 :(得分:0)
我的初步调查如下:
1 struts2-osgi-plugin使用StrutsOsgiListener作为Web上下文侦听器,并且在执行StrutsOsgiListener.contextInitialized方法时,struts2-osgi-plugin将启动嵌入式felix运行时,该运行时通常位于WEB-INF / lib下。至于Struts2OSGi,这个嵌入的felix运行时是felix 1.4.1。
2因为glassfish v3 / v4的内核默认基于felix,并且在启动glassfish域之后,在当前系统中,存在来自glassfish本身的osgi运行时。因此,在将struts2-osgi-plugin相关应用程序部署到glassfish v3 / v4时,会有两个osgi运行时,这会导致与部署环境发生冲突,而且在尝试生成bundleactivator时会发生强制转换异常。
然后,如何使它们正常工作?
我的计划是扩展struts2-osgi-plugin, 1)创建一个GlassfishOsgiHost,它实现OsgiHost接口以满足glassfish部署场景。注意:glassfish本身也可以被视为osgi容器。
2)需要一些方法来配置struts2-osgi-plugin以告诉它当前部署的env是否具有osgi运行时以便调用正确的OsgiHost实现
事情并不容易,我会尝试,同时,如果你对我的想法感兴趣,请告诉我,我们可以一起做。
答案 4 :(得分:0)
我已经在github上创建了一个repo 1,我将开始做这样的扩展,一旦完成这样的扩展,我会回复你。
答案 5 :(得分:0)
关于克里斯蒂娜所说的“从WEB-INF / classes / bundles / 2文件夹中删除所有包”,我需要说一旦你部署了demo(包括myosgi包)一次,你从中移除所有包WEB-INF / classes / bundles / 2文件夹并希望再次部署演示,在server.log中,您仍然可以找到myosgi和其他捆绑包相关的异常。
原因是你在第一次部署demo之后,struts2-osgi-plugin将已部署的bundle保存到osgi缓存中,例如。对于Windows,这个缓存是“C:\ DOCUME~1 \ ADMINI~1 \ LOCALS~1 \ Temp.felix-cache”,因此,在部署demo之前(从WEB-INF / classes / bundles / 2中删除所有bundle)文件夹)第二次,请删除缓存。
事实上,我已经确认在删除缓存并再次部署不包含bundle / 2的任何bundle的demo之后,在server.log中,任何异常都不会发生。 并且,我还确认在“C:\ DOCUME~1 \ ADMINI~1 \ LOCALS~1 \ Temp.felix-cache”中,安装了三个软件包,如下所示:
1)org.apache.felix.main 4.0.2
bundle.location:file:/ D:/1214/glassfish2/glassfish3/glassfish/osgi/felix/bin/felix.jar
2)org.apache.felix.shell 1.0.2
bundle.location:file:/ D:/1214/glassfish2/glassfish3/glassfish/domains/domain1/applications/osgi-2.3.1/WEB-INF/lib/org.apache.felix.shell-1.0.2的.jar
3)只有一个bundle.id文件,我想它应该是系统包。
但是,有关上述三个捆绑包需要调查的问题,
1)在demo的WEB-INF / lib中,org.apache.felix.main的版本是1.4.1而不是4.0.2,4.0.2应该是glassfish的felix版本(这一点可以通过bundle位置确认)
2)为什么第三个包只是bundle.id文件而没有其他安装信息。
无论出现这些问题,似乎都可以在同一个应用服务器中运行两个OSGi运行时。
但是,我会看到在添加struts2-osgi-admin-bundle-2.3.1.jar时会发生什么,会发生什么。
所以,可能有两个调查方向:
1)在glassfish中有两个OSGi运行时 2)在oder中扩展struts2-osgi-plugin,让bundle只能由glassfish osgi运行时管理
答案 6 :(得分:0)
深入地说,在server.log中添加struts2-osgi-admin-bundle-2.3.1.jar时,会发生以下两个主要异常,
1)无法解析package = javax.servlet
[#| 2013-01-11T15:22:58.296 + 0900 | SEVERE | glassfish 4.0 | javax.enterprise.logging.stderr | _ThreadID = 85; _TreadName = FelixStartLevel; _TimeMillis = 1357885378296; _LevelValue = 1000; | org。 osgi.framework.BundleException:bundle 1中的未解决约束:package; (包=的javax.servlet) 在org.apache.felix.framework.Felix._resolveBundle(Felix.java:1792) 在org.apache.felix.framework.Felix._startBundle(Felix.java:1652) 在org.apache.felix.framework.Felix.startBundle(Felix.java:1588) 在org.apache.felix.framework.Felix.setFrameworkStartLevel(Felix.java:1180) 在org.apache.felix.framework.StartLevelImpl.run(StartLevelImpl.java:265) 在java.lang.Thread.run(Thread.java:722) |#]
包由struts2-osgi-admin-bundle-2.3.1.jar导入。
2)无法找到类org.apache.struts2.osgi.admin.actions.BundlesAction
[#| 2013-01-11T15:23:00.578 + 0900 | INFO | glassfish 4.0 | javax.enterprise.logging.stdout | _ThreadID = 79; _TreadName = admin-listener(1); _ TimeMillis = 1357885380578; _LevelValue = 800; | 15:23:00:578 DEBUG(com.opensymphony.xwork2.config.providers.XmlConfigurationProvider:72) - 找不到动作的类[org.apache.struts2.osgi.admin.actions.BundlesAction] java.lang.ClassNotFoundException:无法找到类org.apache.struts2.osgi.admin.actions.BundlesAction 在org.apache.struts2.osgi.DefaultBundleAccessor.loadClass(DefaultBundleAccessor.java:115) at org.apache.struts2.osgi.DelegatingObjectFactory.getClassInstance(DelegatingObjectFactory.java:77) 在com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.verifyAction(XmlConfigurationProvider.java:416) 在com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.addAction(XmlConfigurationProvider.java:370) ...
所以,首先,我们必须调查“C:\ DOCUME~1 \ ADMINI~1 \ LOCALS~1 \ Temp.felix-cache”中包的安装逻辑。
答案 7 :(得分:0)
我认为我已经知道为什么将org.apache.felix.main 4.0.2安装到felix缓存而不是WEB-INF / lib / org.apache.felix.framework-1.4.1.jar中的一些原因。通常,应该安装org.apache.felix.framework-1.4.1.jar,你可以通过tomcat确认这一点。
好的,我开始说原因是:
问题发生在FelixOsgiHost.startFelix()151行,
bundleJarsLevel1.add(getJarUrl(ServiceTracker.class));
在glassfish场景中,getJarUrl(ServiceTracker.class)返回... / glassfish3 / glassfish / osgi / felix / bin / felix.jar而不是glassfish3 / glassfish / domains / domain1 / applications / osgi-2.3.1 / WEB -INF / lib / org.apache.felix.framework-1.4.1.jar因为glassfish osgi运行时,这将导致捆绑部署的许多冲突。
如果我们更新插件的felix版本,也许问题可能会消失,但是,用于插件的osgi嵌入模式应该是好的并且不受glassfish osgi运行时的影响。我们可以想象如果嵌入的osgi运行时来自equinox,同样的问题仍然会发生。
我将通过硬编码getJarUrl(ServiceTracker.class)进行快速测试,以确定问题是否真正由它引起。
答案 8 :(得分:0)
现在,关于将felix 1.4.1更新为4.0.2,我已完成增强,please seeing my fixing here
基本上,felix 1.x和4.x之间的实现差异很大,所以我们需要更新插件的pom和felix嵌入式启动方式的一些地方。
我在tomcat 7下测试过。
答案 9 :(得分:0)
事实证明,根据this post,你可以使用GlasssFish_Platform = Static来启动没有OSGi的GlassFish,在这种情况下,插件可以工作,因为当插件自己启动时没有现有的OSGi运行时。但是我并不认为这是一个解决方案,更多的是解决方法,因为它会导致其他问题(例如GlassFish管理控制台,这是一个OSGi包,不可用)。
答案 10 :(得分:0)
实际上,我昨天已经对问题进行了大量调查,我们必须解决一个关键问题:
在战争中嵌入osgi运行时并在现有的osgi运行时下进行战争时,我们必须小心处理一些系统包。
以下是sahoo回复中的一篇有价值的文章。
我将根据帖子制作一个新的实现,因为现在,我遇到了这个问题。