Инъекция Guice и EJB (перехватчик?)

Я отлаживал много-много часов, но не могу понять, почему код не работает. Два класса обслуживания, аннотированные одинаковым образом, демонстрируют различное поведение перехватчика.

Трассировка стека №1:

Daemon Thread [http-thread-pool-8080(1)] (Suspended (breakpoint at line 120 in UserService))    
    UserService.saveUserOnLogin(UserBE) line: 120   
    NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]  
    NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57  
    DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43  
    Method.invoke(Object, Object...) line: 601  
    EJBSecurityManager.runMethod(Method, Object, Object[]) line: 1052   
    EJBSecurityManager.invoke(Method, boolean, Object, Object[]) line: 1124 
    StatelessSessionContainer(BaseContainer).invokeBeanMethod(EjbInvocation) line: 5388 
    EjbInvocation.invokeBeanMethod() line: 619  
    AroundInvokeChainImpl.invokeNext(int, InterceptorManager$AroundInvokeContext) line: 800 
    EjbInvocation.proceed() line: 571   
    _GuiceInterceptor_Serializable(GuiceInterceptor).injectByGuice(InvocationContext) line: 24  
    NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]  
    NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57  
    DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43  
    Method.invoke(Object, Object...) line: 601  
    AroundInvokeInterceptor.intercept(InterceptorManager$AroundInvokeContext) line: 861 
    AroundInvokeChainImpl.invokeNext(int, InterceptorManager$AroundInvokeContext) line: 800 
    EjbInvocation.proceed() line: 571   
    _SystemInterceptorProxy_Serializable(SystemInterceptorProxy).doAround(InvocationContext, Method) line: 162  
    _SystemInterceptorProxy_Serializable(SystemInterceptorProxy).aroundInvoke(InvocationContext) line: 144  
    NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]  
    NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57  
    DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43  
    Method.invoke(Object, Object...) line: 601  
    AroundInvokeInterceptor.intercept(InterceptorManager$AroundInvokeContext) line: 861 
    AroundInvokeChainImpl.invokeNext(int, InterceptorManager$AroundInvokeContext) line: 800 
    InterceptorManager.intercept(InterceptorManager$InterceptorChain, InterceptorManager$AroundInvokeContext) line: 370 
    StatelessSessionContainer(BaseContainer).__intercept(EjbInvocation) line: 5360  
    StatelessSessionContainer(BaseContainer).intercept(EjbInvocation) line: 5348    
    EJBLocalObjectInvocationHandler.invoke(Class, Method, Object[]) line: 214   
    EJBLocalObjectInvocationHandlerDelegate.invoke(Object, Method, Object[]) line: 88   
    $Proxy209.saveUserOnLogin(UserBE) line: not available   
    __EJB31_Generated__UserService__Intf____Bean__.saveUserOnLogin(UserBE) line: not available  
    LoginUserHandler.saveUser(UserDTO) line: 165    
    LoginUserHandler.loginUser(UserDTO) line: 123   
    LoginUserHandler.loginWithOAuth(String, String, String, String) line: 158   
    LoginUserHandler.execute(LoginUser, ExecutionContext) line: 103 
    LoginUserHandler.execute(Action, ExecutionContext) line: 1  
    GuiceDispatch(AbstractDispatch).doExecute(A, ExecutionContext) line: 81 
    GuiceDispatch(AbstractDispatch).execute(A) line: 68 
    HupaDispatchServlet(AbstractSecureDispatchServlet).execute(String, Action<?>) line: 29  
    HupaDispatchServlet.execute(String, Action<?>) line: 56 
    NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]  
    NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57  
    DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43  
    Method.invoke(Object, Object...) line: 601  
    RPC.invokeAndEncodeResponse(Object, Method, Object[], SerializationPolicy, int) line: 569   
    HupaDispatchServlet(RemoteServiceServlet).processCall(String) line: 208 
    HupaDispatchServlet(RemoteServiceServlet).processPost(HttpServletRequest, HttpServletResponse) line: 248    
    HupaDispatchServlet(AbstractRemoteServiceServlet).doPost(HttpServletRequest, HttpServletResponse) line: 62  
    HupaDispatchServlet(HttpServlet).service(HttpServletRequest, HttpServletResponse) line: 688 
    HupaDispatchServlet(HttpServlet).service(ServletRequest, ServletResponse) line: 770 
    ServletDefinition.doService(ServletRequest, ServletResponse) line: 263  
    ServletDefinition.service(ServletRequest, ServletResponse) line: 178    
    ManagedServletPipeline.service(ServletRequest, ServletResponse) line: 91    
    FilterChainInvocation.doFilter(ServletRequest, ServletResponse) line: 62    
    ManagedFilterPipeline.dispatch(ServletRequest, ServletResponse, FilterChain) line: 118  
    GuiceFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 113    
    ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 256  
    ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 217  
    StandardWrapperValve.invoke(Request, Response) line: 279    
    StandardContextValve.invoke(Request, Response) line: 175    
    StandardPipeline.doInvoke(Request, Response, boolean) line: 655 
    StandardPipeline.invoke(Request, Response) line: 595    
    StandardHostValve.invoke(Request, Response) line: 161   
    CoyoteAdapter.doService(Request, Request, Response, Response) line: 331 
    CoyoteAdapter.service(Request, Response) line: 231  
    ContainerMapper$AdapterCallable.call() line: 317    
    ContainerMapper.service(Request, Response) line: 195    
    ProcessorTask.invokeAdapter() line: 849 
    ProcessorTask.doProcess() line: 746 
    ProcessorTask.process(InputStream, OutputStream) line: 1045 
    DefaultProtocolFilter.execute(Context) line: 228    
    HttpProtocolChain(DefaultProtocolChain).executeProtocolFilter(Context, int) line: 137   
    HttpProtocolChain(DefaultProtocolChain).execute(Context, int) line: 104 
    HttpProtocolChain(DefaultProtocolChain).execute(Context) line: 90   
    HttpProtocolChain.execute(Context) line: 79 
    ProtocolChainContextTask.doCall() line: 54  
    ProtocolChainContextTask(SelectionKeyContextTask).call() line: 59   
    ProtocolChainContextTask(ContextTask).run() line: 71    
    FixedThreadPool$BasicWorker(AbstractThreadPool$Worker).doWork() line: 532   
    FixedThreadPool$BasicWorker(AbstractThreadPool$Worker).run() line: 513  
    HttpWorkerThread(Thread).run() line: 722    

Трассировка стека № 2

Daemon Thread [http-thread-pool-8080(2)] (Suspended (entry into method synchronizeHeaders in MessageService))   
__EJB31_Generated__MessageService__Intf____Bean__(MessageService).synchronizeHeaders(String) line: 93   
FetchMessagesHandler.executeInternal(FetchMessages, ExecutionContext) line: 80  
FetchMessagesHandler.executeInternal(Action, ExecutionContext) line: 1  
FetchMessagesHandler(AbstractSessionHandler<A,R>).executeWithRetries(A, ExecutionContext, int) line: 127    
FetchMessagesHandler(AbstractSessionHandler<A,R>).execute(A, ExecutionContext) line: 97 
GuiceDispatch(AbstractDispatch).doExecute(A, ExecutionContext) line: 81 
GuiceDispatch(AbstractDispatch).execute(A) line: 68 
HupaDispatchServlet(AbstractSecureDispatchServlet).execute(String, Action<?>) line: 29  
HupaDispatchServlet.execute(String, Action<?>) line: 56 
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]  
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57  
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43  
Method.invoke(Object, Object...) line: 601  
RPC.invokeAndEncodeResponse(Object, Method, Object[], SerializationPolicy, int) line: 569   
HupaDispatchServlet(RemoteServiceServlet).processCall(String) line: 208 
HupaDispatchServlet(RemoteServiceServlet).processPost(HttpServletRequest, HttpServletResponse) line: 248    
HupaDispatchServlet(AbstractRemoteServiceServlet).doPost(HttpServletRequest, HttpServletResponse) line: 62  
HupaDispatchServlet(HttpServlet).service(HttpServletRequest, HttpServletResponse) line: 688 
HupaDispatchServlet(HttpServlet).service(ServletRequest, ServletResponse) line: 770 
ServletDefinition.doService(ServletRequest, ServletResponse) line: 263  
ServletDefinition.service(ServletRequest, ServletResponse) line: 178    
ManagedServletPipeline.service(ServletRequest, ServletResponse) line: 91    
FilterChainInvocation.doFilter(ServletRequest, ServletResponse) line: 62    
ManagedFilterPipeline.dispatch(ServletRequest, ServletResponse, FilterChain) line: 118  
GuiceFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 113    
ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 256  
ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 217  
StandardWrapperValve.invoke(Request, Response) line: 279    
StandardContextValve.invoke(Request, Response) line: 175    
StandardPipeline.doInvoke(Request, Response, boolean) line: 655 
StandardPipeline.invoke(Request, Response) line: 595    
StandardHostValve.invoke(Request, Response) line: 161   
CoyoteAdapter.doService(Request, Request, Response, Response) line: 331 
CoyoteAdapter.service(Request, Response) line: 231  
ContainerMapper$AdapterCallable.call() line: 317    
ContainerMapper.service(Request, Response) line: 195    
ProcessorTask.invokeAdapter() line: 849 
ProcessorTask.doProcess() line: 746 
ProcessorTask.process(InputStream, OutputStream) line: 1045 
DefaultProtocolFilter.execute(Context) line: 228    
HttpProtocolChain(DefaultProtocolChain).executeProtocolFilter(Context, int) line: 137   
HttpProtocolChain(DefaultProtocolChain).execute(Context, int) line: 104 
HttpProtocolChain(DefaultProtocolChain).execute(Context) line: 90   
HttpProtocolChain.execute(Context) line: 79 
ProtocolChainContextTask.doCall() line: 54  
ProtocolChainContextTask(SelectionKeyContextTask).call() line: 59   
ProtocolChainContextTask(ContextTask).run() line: 71    
FixedThreadPool$BasicWorker(AbstractThreadPool$Worker).doWork() line: 532   
FixedThreadPool$BasicWorker(AbstractThreadPool$Worker).run() line: 513  
HttpWorkerThread(Thread).run() line: 722    

Кажется, что перехватчик не вызывается для класса обслуживания сообщений. Однако это работает для пользовательского класса обслуживания. Почему это могло быть?

Класс службы сообщений:

@Stateless
@Interceptors(GuiceInterceptor.class)
public class MessageService {

    /**
     * The gmail folder default.
     */
    private static final String GMAIL_ALL_MAIL = "[Gmail]/All Mail";

    /**
     * The IMAP store cache.
     */
    @Inject
    private IMAPStoreCache imapStoreCache;

    /**
     * The EJB resolver.
     */
    @Inject
    private EJBResolver ejbResolver;

Класс обслуживания пользователя:

@Stateless
@Interceptors(GuiceInterceptor.class)
public class UserService {

    /**
     * The entity manager.
     */
    @PersistenceContext(unitName = "hupa")
    private EntityManager em;

    /**
     * The session provider.
     */
    @Inject
    private Provider<HttpSession> sessionProvider;

И, наконец, перехватчик:

public class GuiceInterceptor {

    @EJB
    private GuiceInjectorHolder injectorHolder;

    @AroundInvoke
    @AroundTimeout
    public Object injectByGuice(InvocationContext invocationContext) throws Exception {
        Injector injector = injectorHolder.getInjector();
        injector.injectMembers(invocationContext.getTarget());
        return invocationContext.proceed();
    }
}

Надеюсь, есть специалисты по этому вопросу, я разочарован;)


person Carl    schedule 15.05.2012    source источник


Ответы (2)


Проблема заключалась в том, что я не мог использовать модификатор final нигде в классе, иначе он не работал бы с Guice. Даже на вспомогательных вспомогательных методах.

person Carl    schedule 17.05.2012

Можете ли вы указать подробности о том, кто вызывает MessageService и как они получили ссылку на него?

Мое первое предположение состоит в том, что тот, кто вызывает MessageService, имеет прямую ссылку на сам экземпляр и не вызывает bean-компонент через созданный контейнером прокси-сервер, полученный с помощью @EJB MessageService service; инъекции или поиска JNDI.

См. этот ответ о важности использования прокси и о том, чем это отличается от использования this или аналогичной прямой ссылки на экземпляр компонента.

person David Blevins    schedule 15.05.2012