Mantis - Resin
Viewing Issue Advanced Details
2332 minor always 01-14-08 13:45 02-13-08 16:19
ferg  
ferg  
normal  
closed 3.1.4  
fixed  
none    
none 3.1.5  
0002332: struts2 objectfactory with scopes
(rep by wesley)

When annotated class with @Component combined with @SessionScoped (or @ConversationScoped/@ApplicationScoped), ResinObjectFactory throws
 
java.lang.RuntimeException:
java.lang.reflect.InvocationTargetException
 
I'm using s080111 snapshot.

Notes
(0002651)
wesleywu   
01-15-08 04:26   
1. First test

Source:
=============================================
package com.mycompany.actions;
 
// no @Component
public class ListArticleAction extends ActionSupport {
 @In
 ArticleListBuilder articleListbuilder;

 public String execute() {
    ...
 }
}
=============================================
package com.mycompany.blocks;
 
@Component
@SessionScoped
public class ArticleListBuilder {
    ...
}
=============================================
Stacktrace:
 
2008-01-15 16:54:40,718 4970 ERROR [http--8080-4] ResinObjectFactory (51) - com.caucho.config.ConfigException: com.mycompany.actions.ListArticleAction.articleListbuilder: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
 at com.caucho.webbeans.inject.ComponentInject.inject(ComponentInject.java:69)
 at com.caucho.webbeans.component.ComponentImpl.init(ComponentImpl.java:461)
 at com.caucho.webbeans.component.ComponentImpl.create(ComponentImpl.java:413)
 at com.caucho.webbeans.component.ComponentImpl.get(ComponentImpl.java:365)
 at com.caucho.xwork2.ResinObjectFactory.buildBean(ResinObjectFactory.java:49) // return component.get();
 at com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:154)
 at com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:143)
 at com.opensymphony.xwork2.ObjectFactory.buildAction(ObjectFactory.java:113)
 at com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:275)
 at com.opensymphony.xwork2.DefaultActionInvocation.init(DefaultActionInvocation.java:365)
 at com.opensymphony.xwork2.DefaultActionInvocation.access$000(DefaultActionInvocation.java:38)
 at com.opensymphony.xwork2.DefaultActionInvocation$1.doProfiling(DefaultActionInvocation.java:83)
 at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
 at com.opensymphony.xwork2.DefaultActionInvocation.<init>(DefaultActionInvocation.java:74)
 at com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:189)
 at org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:41)
 at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:494)
 at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:419)
 at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:87)
 at com.opensymphony.module.sitemesh.filter.PageFilter.parsePage(PageFilter.java:119)
 at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:55)
 at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:87)
 at org.apache.struts2.dispatcher.ActionContextCleanUp.doFilter(ActionContextCleanUp.java:99)
 at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:87)
 at com.yaqu.servlet.filter.gzip.GZIPFilter.doFilter(GZIPFilter.java:36)
 at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:87)
 at com.caucho.server.webapp.WebAppFilterChain.doFilter(WebAppFilterChain.java:181)
 at com.caucho.server.dispatch.ServletInvocation.service(ServletInvocation.java:266)
 at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:268)
 at com.caucho.server.port.TcpConnection.run(TcpConnection.java:603)
 at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:721)
 at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:643)
 at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
 at com.caucho.webbeans.bytecode.ScopeAdapter.wrap(ScopeAdapter.java:73)
 at com.caucho.webbeans.component.ClassComponent.get(ClassComponent.java:267)
 at com.caucho.webbeans.inject.ComponentInject.inject(ComponentInject.java:63)
 ... 32 more
Caused by: java.lang.reflect.InvocationTargetException
 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
 at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
 at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
 at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
 at com.caucho.webbeans.bytecode.ScopeAdapter.wrap(ScopeAdapter.java:68)
 ... 34 more
Caused by: java.lang.NoSuchMethodError: com.mycompany.blocks.ArticleListBuilder: method <init>()V not found
 at com.mycompany.blocks.ArticleListBuilder$ScopeProxy.<init>(Unknown Source)
 ... 39 more
 
[16:54:40.720] {http--8080-4} com.mycompany.actions.ListArticleAction.articleListbuilder: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException






 
2. Second test
 
And then I change the inject method to constructor inject:
=============================================
package com.mycompany.actions;
 
// no @Component
public class ListArticleAction extends ActionSupport {
 ArticleListBuilder articleListbuilder;
 
 public ListArticleAction(@In ArticleListBuilder articleListbuilder) {
  this.articleListbuilder = articleListbuilder;
  System.out.println(this);
  System.out.println(articleListbuilder);
 }
 


 public String execute() {
    ...
 }
}
=============================================
No exception occurred, but every time I refresh the web page,
system output was like below
 
com.mycompany.actions.ListArticleAction@183bff8
com.mycompany.blocks.ArticleListBuilder@b04d34
com.mycompany.actions.ListArticleAction@f94dad
com.mycompany.blocks.ArticleListBuilder@15ab821
com.mycompany.actions.ListArticleAction@5a5519
com.mycompany.blocks.ArticleListBuilder@88dd83
com.mycompany.actions.ListArticleAction@1a24c3f
com.mycompany.blocks.ArticleListBuilder@3bdcbc
com.mycompany.actions.ListArticleAction@15b73eb
com.mycompany.blocks.ArticleListBuilder@1176de6

The @SessionScope on ArticleListBuilder was not applied.






3. Third test

When applied @Component & @SessionScoped to action class, no matter what scope was applied to those classes need to be injected, every component turned into session scoped.
 
code:
=============================================
package com.mycompany.actions;
 
@SessionScoped
@Component
public class ListArticleAction extends ActionSupport {
 ArticleListBuilder articleListbuilder;

 public ListArticleAction(@In ArticleListBuilder articleListbuilder) {
  this.articleListbuilder = articleListbuilder;
 }

 public String execute() {
  System.out.println(this);
  System.out.println(articleListbuilder);
    ...
 }
}
 
=============================================
package com.mycompany.blocks;
 
@RequestScoped
@Component
public class ArticleListBuilder {
    ...
}
=============================================
 
output:
com.mycompany.actions.ListArticleAction@111e6b9
com.mycompany.blocks.ArticleListBuilder@42a751 // should be request scoped, but seems to be session scoped
com.mycompany.actions.ListArticleAction@111e6b9
com.mycompany.blocks.ArticleListBuilder@42a751
com.mycompany.actions.ListArticleAction@111e6b9
com.mycompany.blocks.ArticleListBuilder@42a751
com.mycompany.actions.ListArticleAction@111e6b9
com.mycompany.blocks.ArticleListBuilder@42a751






4. My thought

It seems webbeans container only checks the scope when requesting the top class instance.
 
Create: If no existing instance in the scope, a new instance should be created. After a new instance was created, container injects its members (also created new instance), and returns the top instance.
 
Reuse: If there was an instance in the current scope, then container simply returns the instance, without checking the members' scope and reinjecting its memebers if neccesary (e.g. the member's scope is narrower than the top instance)
(0002774)
ferg   
02-13-08 16:19   
ioc/0535