@Startup @Singleton @PostConstruct дает исключение RunTimeException (не удалось вызвать PostConstruct для вновь созданного экземпляра bean-компонента)

Я пытаюсь создать bean-компонент, который запускается при запуске, чтобы выполнить миграцию имеющихся у нас данных. Он помечен как bean-компонент @Singleton @Startup, но @PostConstruct дает сбой, но я понятия не имею, почему.

Это код:

@Startup
@Singleton
@DependsOn("SearchInitializer")
public class SearchMigrator {
    @Inject
    @Any
    private Instance<MigrationScenario> migrationScenarios;
    @Inject
    private SearchRepository repository;
    private List<MigrationScenario> sortedScenarioList;

    @PostConstruct
    public void doMigration() {
        (call run() on each MigrationScenario)
    }
}

SearchInitializer также является bean-компонентом @Startup @Singleton с аннотацией @PostConstruct для метода, который работает нормально (также до этого bean-компонента, поэтому @DependsOn работает правильно). SearchRepository - это bean-компонент @Stateless, который отправляется в базу данных.

Однако, если я запускаю этот код, я получаю следующее исключение:

Create: java.lang.RuntimeException: Could not invoke PostConstruct on the newly created bean instance

Кто-нибудь знает, что я делаю не так?

ИЗМЕНИТЬ

Дополнительная информация: я подозреваю, что виноват "@Inject private SearchRepository репозиторий". Когда я удаляю инъекцию этого репозитория, он загружается нормально. Если я этого не сделаю, я получаю эту ошибку:

16:10:39,531 ERROR [org.jboss.kernel.plugins.dependency.AbstractKernelController] Error installing to Start: name=startup-singleton-initiator:topLevelUnit=xxx-war.war,unit=xxx-war.war,bean=SearchInitializer aliases=[startup-singleton-initiator:bean=SearchInitializer,topLevelUnit=xxx-war.war,unit=xxx-war.war] state=Create: java.lang.RuntimeException: Could not invoke PostConstruct on the newly created bean instance
at org.jboss.ejb3.singleton.impl.container.SingletonEJBInstanceManagerImpl.create(SingletonEJBInstanceManagerImpl.java:137) [:1.0.2]
at org.jboss.ejb3.singleton.impl.container.SingletonEJBInstanceManagerImpl.get(SingletonEJBInstanceManagerImpl.java:152) [:1.0.2]
at org.jboss.ejb3.singleton.deployer.StartupSingletonInitiator.start(StartupSingletonInitiator.java:84) [:1.0.2]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [:1.6.0_30]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [:1.6.0_30]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [:1.6.0_30]
at java.lang.reflect.Method.invoke(Method.java:597) [:1.6.0_30]
at org.jboss.reflect.plugins.introspection.ReflectionUtils.invoke(ReflectionUtils.java:60) [jboss-reflect.jar:2.2.1.SP1]
at org.jboss.reflect.plugins.introspection.ReflectMethodInfoImpl.invoke(ReflectMethodInfoImpl.java:168) [jboss-reflect.jar:2.2.1.SP1]
at org.jboss.joinpoint.plugins.BasicMethodJoinPoint.dispatch(BasicMethodJoinPoint.java:66) [jboss-reflect.jar:2.2.1.SP1]
at org.jboss.kernel.plugins.dependency.KernelControllerContextAction$JoinpointDispatchWrapper.execute(KernelControllerContextAction.java:257) [jboss-kernel.jar:2.2.0.SP2]
at org.jboss.kernel.plugins.dependency.ExecutionWrapper.execute(ExecutionWrapper.java:47) [jboss-kernel.jar:2.2.0.SP2]
at org.jboss.kernel.plugins.dependency.KernelControllerContextAction.dispatchExecutionWrapper(KernelControllerContextAction.java:125) [jboss-kernel.jar:2.2.0.SP2]
at org.jboss.kernel.plugins.dependency.KernelControllerContextAction.dispatchJoinPoint(KernelControllerContextAction.java:72) [jboss-kernel.jar:2.2.0.SP2]
at org.jboss.kernel.plugins.dependency.LifecycleAction.installActionInternal(LifecycleAction.java:202) [jboss-kernel.jar:2.2.0.SP2]
at org.jboss.kernel.plugins.dependency.InstallsAwareAction.installAction(InstallsAwareAction.java:54) [jboss-kernel.jar:2.2.0.SP2]
at org.jboss.kernel.plugins.dependency.InstallsAwareAction.installAction(InstallsAwareAction.java:42) [jboss-kernel.jar:2.2.0.SP2]
at org.jboss.dependency.plugins.action.SimpleControllerContextAction.simpleInstallAction(SimpleControllerContextAction.java:62) [jboss-dependency.jar:2.2.0.SP2]
at org.jboss.dependency.plugins.action.AccessControllerContextAction.install(AccessControllerContextAction.java:71) [jboss-dependency.jar:2.2.0.SP2]
at org.jboss.dependency.plugins.AbstractControllerContextActions.install(AbstractControllerContextActions.java:51) [jboss-dependency.jar:2.2.0.SP2]
at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:379) [jboss-dependency.jar:2.2.0.SP2]
at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:2044) [jboss-dependency.jar:2.2.0.SP2]
at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:1083) [jboss-dependency.jar:2.2.0.SP2]
at org.jboss.dependency.plugins.AbstractController.executeOrIncrementStateDirectly(AbstractController.java:1322) [jboss-dependency.jar:2.2.0.SP2]
at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1246) [jboss-dependency.jar:2.2.0.SP2]
at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1139) [jboss-dependency.jar:2.2.0.SP2]
at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:939) [jboss-dependency.jar:2.2.0.SP2]
at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:654) [jboss-dependency.jar:2.2.0.SP2]
at org.jboss.deployers.plugins.deployers.DeployersImpl.change(DeployersImpl.java:1983) [:2.2.2.GA]
at org.jboss.deployers.plugins.deployers.DeployersImpl.process(DeployersImpl.java:1076) [:2.2.2.GA]
at org.jboss.deployers.plugins.main.MainDeployerImpl.process(MainDeployerImpl.java:679) [:2.2.2.GA]
at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:380) [:6.1.0.Final]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [:1.6.0_30]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [:1.6.0_30]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [:1.6.0_30]
at java.lang.reflect.Method.invoke(Method.java:597) [:1.6.0_30]
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:157) [:6.0.0.GA]
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:96) [:6.0.0.GA]
at org.jboss.mx.server.Invocation.invoke(Invocation.java:88) [:6.0.0.GA]
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:271) [:6.0.0.GA]
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:670) [:6.0.0.GA]
at org.jboss.system.server.jmx.MBeanServerWrapper.invoke(MBeanServerWrapper.java:138) [:6.1.0.Final]
at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1427) [:1.6.0_30]
at javax.management.remote.rmi.RMIConnectionImpl.access$200(RMIConnectionImpl.java:72) [:1.6.0_30]
at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1265) [:1.6.0_30]
at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1360) [:1.6.0_30]
at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:788) [:1.6.0_30]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [:1.6.0_30]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [:1.6.0_30]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [:1.6.0_30]
at java.lang.reflect.Method.invoke(Method.java:597) [:1.6.0_30]
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:303) [:1.6.0_30]
at sun.rmi.transport.Transport$1.run(Transport.java:159) [:1.6.0_30]
at java.security.AccessController.doPrivileged(Native Method) [:1.6.0_30]
at sun.rmi.transport.Transport.serviceCall(Transport.java:155) [:1.6.0_30]
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535) [:1.6.0_30]
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790) [:1.6.0_30]
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649) [:1.6.0_30]
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [:1.6.0_30]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [:1.6.0_30]
at java.lang.Thread.run(Thread.java:662) [:1.6.0_30]
Caused by: java.lang.RuntimeException: java.lang.NullPointerException
at org.jboss.ejb3.singleton.aop.impl.AOPBasedSingletonContainer.invokeCallback(AOPBasedSingletonContainer.java:1065) [:1.0.2]
at org.jboss.ejb3.EJBContainer.invokePostConstruct(EJBContainer.java:1396) [:1.7.21]
at org.jboss.ejb3.singleton.aop.impl.AOPBasedSingletonContainer.postConstruct(AOPBasedSingletonContainer.java:762) [:1.0.2]
at org.jboss.ejb3.singleton.impl.container.SingletonEJBInstanceManagerImpl.create(SingletonEJBInstanceManagerImpl.java:133) [:1.0.2]
... 60 more
Caused by: java.lang.NullPointerException
at org.jboss.ejb3.EJBContainer.getApplicationException(EJBContainer.java:509) [:1.7.21]
at org.jboss.ejb3.singleton.aop.impl.ConstructionInvocationContextAdapter.getApplicationException(ConstructionInvocationContextAdapter.java:62) [:1.0.2]
at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.handleExceptionInOurTx(CMTTxInterceptor.java:163) [:0.0.2]
at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:251) [:0.0.2]
at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.requiresNew(CMTTxInterceptor.java:392) [:0.0.2]
at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.invoke(CMTTxInterceptor.java:211) [:0.0.2]
at org.jboss.ejb3.tx2.aop.CMTTxInterceptorWrapper.invoke(CMTTxInterceptorWrapper.java:52) [:0.0.2]
at org.jboss.aop.joinpoint.ConstructionInvocation.invokeNext(ConstructionInvocation.java:80) [jboss-aop.jar:2.2.2.GA]
at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76) [:1.0.0.GA]
at org.jboss.aop.joinpoint.ConstructionInvocation.invokeNext(ConstructionInvocation.java:80) [jboss-aop.jar:2.2.2.GA]
at org.jboss.ejb3.core.context.CurrentInvocationContextInterceptor.invoke(CurrentInvocationContextInterceptor.java:47) [:1.7.21]
at org.jboss.aop.joinpoint.ConstructionInvocation.invokeNext(ConstructionInvocation.java:80) [jboss-aop.jar:2.2.2.GA]
at org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor.setup(InvocationContextInterceptor.java:90) [:1.1.3]
at org.jboss.aop.advice.org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor_z_setup_1631131631.invoke(InvocationContextInterceptor_z_setup_1631131631.java) [:]
at org.jboss.aop.joinpoint.ConstructionInvocation.invokeNext(ConstructionInvocation.java:80) [jboss-aop.jar:2.2.2.GA]
at org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor.invoke(CurrentInvocationInterceptor.java:67) [:1.0.1]
at org.jboss.aop.joinpoint.ConstructionInvocation.invokeNext(ConstructionInvocation.java:80) [jboss-aop.jar:2.2.2.GA]
at org.jboss.ejb3.singleton.aop.impl.AOPBasedSingletonContainer.invokeCallback(AOPBasedSingletonContainer.java:1061) [:1.0.2]
... 63 more

Если я отлаживаю процесс загрузки, я вижу, что репозиторий фактически проксируется (что также поддерживается ссылками на АОП в трассировке стека).

Но все равно не удалось разобраться! Кто-нибудь?


person gjoris    schedule 30.10.2012    source источник
comment
Ах, да, возможно, полезная информация: я работаю на JBoss 6.1 Final - так что эта конструкция не должна быть проблемой.   -  person gjoris    schedule 30.10.2012


Ответы (2)


Хорошо, я понял, в чем проблема. Собственно, мой ответ будет касаться общего способа обработки такого рода ошибок. Проблема с этой ошибкой - это сам JBoss: сервер приложений фактически съедает настоящую ошибку и просто бросает вам в лицо исключение NullPointerException.

Что я сделал, чтобы получить свою фактическую ошибку, так это временно ввел этот взлом в свой код, просто чтобы узнать, что происходит:

@PostConstruct
public void doMigration() throws Throwable {
    try {
        runAllFoundScenarios();
    } catch (Throwable e) {
        System.out.println("Cause: " + e.getCause());
        System.out.println("Message: " + e.getMessage());
        System.out.println("Class: " + e.getClass());
        System.out.println("StackTrace: " + e.getStackTrace());
        throw e;
    }
}

Таким образом, я смог определить настоящую причину, просмотрев журнал, что позволило мне решить эту проблему. Я мог найти повсюду в Интернете людей с одной и той же проблемой, но никто никогда не публиковал обходные пути, поэтому я надеюсь, что этот ответ поможет вам узнать, что на самом деле происходит.

К вашему сведению, для меня это была проблема JPA с внедренным репозиторием.

person gjoris    schedule 31.10.2012

Как указано в аннотации PosConstruct (PostConstruct javadoc), методы, аннотированные PostConstruct, не могут запускать проверенные исключения.

Итак, возникает естественный вопрос: как мы должны сообщать о проблемах при запуске наших beans ?. Создание простого RuntimeException для пропуска проверенного ограничения исключения кажется неправильным способом. Эта практика используется для обозначения ленивой разработки, и многие инструменты для анализа качественного кода будут жаловаться. Кстати, контейнер EJB принимает исключение, как уже упоминалось в исходном вопросе.

Что ж, после некоторого времени в Интернете я не нашел ответа. Для EJB-компонента, похоже, существует приемлемый вариант в иерархии исключений EJBException (EJBException javadoc).

Для обычных компонентов CDI, я думаю, мы можем выбрать некоторые из подклассов RuntimeException, как указано в проверенных исключениях postconstruct

person Jaime Casero    schedule 07.02.2014