2012-07-20 79 views
0

编辑:我所做的更改,因为我觉得我的问题可能会丢失一些技术细节如何避免Struts 1.3.x中ClassCastException由于其类加载策略?

Struts中1.3.x中出现该问题,并通过了以下描述:

当修改相关类Struts(例如ActionForm,Action和/或任何我使用它们的类),那么当我测试我的修改时(而不重新启动我的webapp),我会得到ClassCastException。

如果在进行相同的修改后重新启动我的web应用程序,则没有例外,并且在进行测试时可以看到所做的更改。

这种行为被认为是因为以下原因是正常的:

我的Web容器(weblogic的)被配置为重新加载servlet和类如作改动

我认为不同的ClassLoader在对我的类进行修改时使用。这可能导致ClassCastException。

因此我必须重新启动web应用程序,每次我想测试我的源代码修改...

我想知道的是我能做些什么(编程模式?最佳实践?),以避免这种ClassCastException或避免重新启动webapp来查看我的更改?

这里是堆栈跟踪:

java.lang.ClassCastException: my.package.here.MyActionClassNameHere 
    at org.apache.struts.chain.commands.servlet.CreateAction.getAction(CreateAction.java:65) 
    at org.apache.struts.chain.commands.AbstractCreateAction.execute(AbstractCreateAction.java:91) 
    at org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:51) 
    at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:191) 
    at org.apache.commons.chain.generic.LookupCommand.execute(LookupCommand.java:305) 
    at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:191) 
    at org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:283) 
    at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1914) 
    at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:463) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:821) 
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227) 
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:300) 
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3650) 
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321) 
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2174) 
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1446) 
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201) 
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:173) 

我见过JRebel的有关页面。这可能是一个解决方案,但我没有准备好将其用于我的目的(这是一些使用struts 1.3.x的非常简单的测试)。

我会继续做一些并行测试,了解多一点有关此异常...

+1

我只听说过有关JRebel的好东西,但我从来没有用过它(而且它不是免费的) – 2012-07-20 15:45:42

+0

@JBNizet:Merci pour taréponse^^ (Je ne suis pas s je tes testerai JRebel juste pour mes petits tests ...) – user1199680 2012-07-23 09:43:43

+0

JB Nizet,如果你在那里开源开发也可以免费使用它也可以使用社交计划,它将很快推出=)https:// my.jrebel.com/plans – 2012-07-25 06:56:57

回答

0

默认情况下,Struts 1.3(最新1.3.x)将操作类放入缓存中以优化性能(重新启动部署清除缓存)。这是异常的原因,因为我的修改后的类是由不同的类加载器加载的,而前一个加载器在缓存中。

在检索动作实例(从堆栈跟踪开始)的步骤中发生此异常。

at org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:283) 

By default this version of Struts implements the chain of responsability pattern(使用xml配置文件chain-config.xml)。因此,request processor mentioned above代表行为实例检索(或实例化)到CreationAction实现(在这里显示,在stactrace):

at org.apache.struts.chain.commands.servlet.CreateAction.getAction(CreateAction.java:65) 

以下是解决方案进行修改和donnot要重新部署时避免ClassCastException异常。

解决方案1:

  • 扩展CreateAction与自定义类和重新定义其的getAction()方法

  • 在的getAction():如果super.getAction()的getClass()与新的类加载器不相同,然后通过调用super.createAction()返回一个新实例。() (这意味着我应该在comparin时知道我的Action类的合格类名使用==操作符,否则我不应该比较,总是克负荷与createAction一个新的动作类)

  • Use a custom chain-config.xml指定要使用的自定义CreationAction而不是默认的一个

解决方案2:使用自定义类扩展RequestProcessor,并使用它来代替默认的类(即struts-config.xml中的更新参数)

我认为应该只在开发阶段完成这些工作(以节省一些测试时间),并且应该当在p中时避免由于性能(和安全性)的原因。

我没有空闲时间来添加更多详细的示例代码,配置文件等......我会尽量做一天(别的地方)。但肯定我测试这些,它适用于我的目的:)

1

这是你承担风险时的时间点,你在加载的类的实例两个独立的类加载器。请参阅http://zeroturnaround.com/blog/reloading-objects-classes-classloaders/并查找ClassCastException。文章很好地解释了Java中类加载的核心。

至于JRebel之外的解决方案,您可能只需重新部署应用程序。你说应用程序足够小,所以不需要太多时间。

+0

是的,我的问题完全是由来自不同类加载器的类引起的。这是由于我在更改后没有重新启动部署**,但主要原因还在于Struts 1.3将类放入缓存中以优化性能**。知道我认为我可以找到解决方案来避免这种例外。我希望我能找到空闲时间来写和解释它(大多数知道的东西都在上面的堆栈跟踪中)。 – user1199680 2012-07-28 15:07:50

+0

您的链接非常有益。谢谢 – user1199680 2012-07-28 16:01:30