(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) |
|