【问题标题】:Scope conflicts until batch job finished?批处理作业完成之前的范围冲突?
【发布时间】:2019-03-02 08:34:03
【问题描述】:

技术栈:

  • JBeret (core, se) 1.3.0.Final
  • Hibernate Search (orm, jsr352-core, jsr352-jberet) 5.10.4.Final
  • Weld (servlet-core, se-core) 3.0.5.Final

如果我触发

BatchRuntime.getJobOperator().start( MassIndexingJob.NAME, MassIndexingJob.parameters().forEntity(getDomainObjectClass()).build() );

然后我遇到了无法访问批处理作业外部的任何 CDI 组件(RequestScopedSessionScoped)的情况,直到批处理作业完成。

我该如何解决这个问题?

堆栈跟踪的一部分

 Caused by: org.jboss.weld.contexts.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.enterprise.context.RequestScoped
    at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:647) ~[weld-core-impl-3.0.5.Final.jar:3.0.5.Final]
    at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:89) ~[weld-core-impl-3.0.5.Final.jar:3.0.5.Final]
    at org.jboss.weld.bean.ContextualInstanceStrategy$CachingContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:164) ~[weld-core-impl-3.0.5.Final.jar:3.0.5.Final]
    at org.jboss.weld.bean.ContextualInstance.getIfExists(ContextualInstance.java:63) ~[weld-core-impl-3.0.5.Final.jar:3.0.5.Final]
    at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:87) ~[weld-core-impl-3.0.5.Final.jar:3.0.5.Final]
    at org.jboss.weld.bean.proxy.ProxyMethodHandler.getInstance(ProxyMethodHandler.java:131) ~[weld-core-impl-3.0.5.Final.jar:3.0.5.Final]
    at foo.bar.Baz$Proxy$_$$_WeldClientProxy.getFoo(Unknown Source) ~[classes/:na]

带注释的@ActivateRequestContext 在启动/部署时生成此堆栈跟踪

 Caused by: org.jboss.weld.exceptions.WeldException: WELD-001524: Unable to load proxy class for bean Managed Bean [class foo.bar.Bean] with qualifiers [@Any @Default] with class class foo.bar.Bean using classloader ParallelWebappClassLoader
  context: foobar
  delegate: false
----------> Parent Classloader:
java.net.URLClassLoader@58a9760d

    at org.jboss.weld.bean.proxy.ProxyFactory.getProxyClass(ProxyFactory.java:370)
    at org.jboss.weld.injection.producer.SubclassedComponentInstantiator.createEnhancedSubclass(SubclassedComponentInstantiator.java:113)
    at org.jboss.weld.injection.producer.SubclassedComponentInstantiator.initEnhancedSubclass(SubclassedComponentInstantiator.java:86)
    at org.jboss.weld.injection.producer.SubclassedComponentInstantiator.<init>(SubclassedComponentInstantiator.java:79)
    at org.jboss.weld.injection.producer.SubclassedComponentInstantiator.forInterceptedDecoratedBean(SubclassedComponentInstantiator.java:63)
    at org.jboss.weld.injection.producer.BeanInjectionTarget.initializeAfterBeanDiscovery(BeanInjectionTarget.java:121)
    at org.jboss.weld.injection.producer.InjectionTargetInitializationContext.initialize(InjectionTargetInitializationContext.java:42)
    at org.jboss.weld.injection.producer.InjectionTargetService.initialize(InjectionTargetService.java:63)
    at org.jboss.weld.bootstrap.WeldStartup.deployBeans(WeldStartup.java:475)
    at org.jboss.weld.bootstrap.WeldBootstrap.deployBeans(WeldBootstrap.java:86)
    at org.jboss.weld.environment.servlet.WeldServletLifecycle.initialize(WeldServletLifecycle.java:236)
    at org.jboss.weld.environment.servlet.EnhancedListener.onStartup(EnhancedListener.java:62)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5245)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    ... 42 more
Caused by: org.jboss.weld.exceptions.WeldException: Cannot load variable at 0. Local Variables: Local Variables: []
    at org.jboss.weld.bean.proxy.InterceptedSubclassFactory.addMethodsFromClass(InterceptedSubclassFactory.java:262)
    at org.jboss.weld.bean.proxy.InterceptedSubclassFactory.addMethods(InterceptedSubclassFactory.java:136)
    at org.jboss.weld.bean.proxy.ProxyFactory.createProxyClass(ProxyFactory.java:449)
    at org.jboss.weld.bean.proxy.ProxyFactory.getProxyClass(ProxyFactory.java:362)
    ... 55 more
Caused by: org.jboss.classfilewriter.InvalidBytecodeException: Cannot load variable at 0. Local Variables: Local Variables: []
    at org.jboss.classfilewriter.code.CodeAttribute.aload(CodeAttribute.java:196)
    at org.jboss.weld.bean.proxy.RunWithinInterceptionDecorationContextGenerator.startIfNotOnTop(RunWithinInterceptionDecorationContextGenerator.java:71)
    at org.jboss.weld.bean.proxy.RunWithinInterceptionDecorationContextGenerator.runStartIfNotOnTop(RunWithinInterceptionDecorationContextGenerator.java:148)
    at org.jboss.weld.bean.proxy.InterceptedSubclassFactory.addMethodsFromClass(InterceptedSubclassFactory.java:200)
    ... 58 more

【问题讨论】:

  • 您的意思是批处理作业工作正常,但是您的主应用程序在批处理作业执行时挂起?还是有特定的错误?请分享堆栈跟踪/日志;没有它,有点难以理解发生了什么。
  • JBeret SE 使用 Weld SE 静态单例焊接容器来管理 CDI 组件(请参阅 SEArtifactFactory)。您的应用程序中的这些有问题的 CDI 组件是否由同一个焊接容器实例管理?还是有多个焊接容器实例?
  • 感谢提示,是的 servlet 容器和 jberet 使用相同的 CDI beanmanager 实例
  • 我创建了一个问题JBERET-454 来在 JBeret 端记录和跟踪它。如果您对 JBeret 仍有问题或有任何改进之处,请随时跟进。
  • 我现在解决了这个问题,将我的 servlet 容器中的所有 contextId 引用替换为自定义值

标签: cdi hibernate-search jsr352 jberet weld-se


【解决方案1】:

我不知道 JBeret 到底做了什么,但开箱即用的 Weld SE 激活请求上下文(或会话上下文),这反过来会导致您看到的异常。原因是在 SE 中没有 HTTP 请求(或会话),因此 Weld 根本不知道何时激活它。

尽管“请求”可以有不同的解释,即使在 SE 中也可能是有价值的补充——这就是为什么有支持的方式来激活请求上下文,for instance via interceptor我想这是 JBeret 为你做的事情,这就是 bean 在那里“工作”的原因。

因此,为了能够在 SE 应用程序中使用您的请求范围 bean,您需要采取额外的步骤。但是请注意,上下文可能与 JBeret 批处理作业的上下文不同(您不会看到具有完全相同状态的相同 bean),因为我希望 JBeret 将工作卸载到另一个线程。

【讨论】:

  • 遗憾的是,如果我尝试注释 @ActivateRequestContext,那么我的 WAR 文件将不再启动
猜你喜欢
  • 2017-05-12
  • 1970-01-01
  • 2020-07-23
  • 2011-11-06
  • 1970-01-01
  • 2017-08-04
  • 1970-01-01
  • 2020-10-31
  • 1970-01-01
相关资源
最近更新 更多