带有CDI生成器方法的ClassCastException和来自脚本的groovy类

时间:2014-12-30 20:10:47

标签: groovy jboss-weld weld

我正在学习Groovy语言以及将其与CDI集成的可能性。

在java类路径中,a有一个名为Product的接口。我创建了一个返回Product类型的CDI Producer方法。 在另一个班级,我执行Product的注入,来自CDI Producer Method。

在classpath之外,我用一个简单的groovy类编写了一个groovy脚本,它实现了Product接口。

在CDI Producer Method中,我使用GroovyScriptEngine从脚本中检索Class对象,以创建CDI Bean。

我正在使用

  • 焊接版本2.2.8.Final作为CDI实施。
  • Groovy版本2.3.9。
  • Tomcat服务器7.
  • 也使用JSF 2.2.8。

(认为这个问题只与CDI和Groovy的Weld实现有关)

第一次一切正常。可以在JSF页面中使用创建的bean,单击按钮并在服务器端执行操作,并在浏览器上刷新页面。 groovy脚本类上的所有声明的方法和字段都可以访问并与JSF页面一起使用。 CDI容器也执行@PostConstruct的调用。可以多次调用CDI Producer Method,并且一切正常。

如上所述,第一次一切正常。但是当groovy脚本发生变化时,会抛出ClassCastException

有人可以帮我解决这个问题吗?这是一个Weld / Groovy问题,还是根本不可能?

Product界面:

package test;

/**
 *
 * @author Welyab
 */
@ProductMethodIntercetor
public interface Product {

    public void a();

    public void b();
}

实现Product接口的groovy脚本:

package test

class ProductImplWithGroovy  implements test.Product {
  @javax.annotation.PostConstruct
  def void init(){ 
        println "call init()"
  }

  def void a(){
      println "call a()";
  }

  def void b(){
      println "call b()";
  }

  def void c(){
      println "call c()";
  }
}

生产者类/方法:

package test;

import groovy.util.GroovyScriptEngine;
import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.net.URL;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.Any;
import javax.enterprise.inject.Default;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.CDI;
import javax.enterprise.inject.spi.InjectionTarget;
import javax.enterprise.util.AnnotationLiteral;

/**
 *
 * @author Welyab
 */
public class ProductsTest {

    private static GroovyScriptEngine se;

    static {
        try {
            se = new GroovyScriptEngine(new URL[]{
                new File("c:/users/welyab/desktop").toURI().toURL()
            });
        }
        catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    @Produces
    @ProductProducer
    public Product criarProduto() {
        BeanManager bm = CDI.current().getBeanManager();

        final Class klazz;
        try {
            klazz = se.loadScriptByName("script_test.groovy");
        }
        catch (Exception ex) {
            throw new RuntimeException(ex);
        }
        Class finalKlazz = klazz;

        AnnotatedType annotatedType = bm.createAnnotatedType(finalKlazz);
        InjectionTarget injectionTarget = bm.createInjectionTarget(annotatedType);

        Bean bean = new Bean() {

            @Override
            public Class getBeanClass() {
                return finalKlazz;
            }

            @Override
            public Set getInjectionPoints() {
                return injectionTarget.getInjectionPoints();
            }

            @Override
            public boolean isNullable() {
                return false;
            }

            @Override
            public Object create(CreationalContext creationalContext) {
                Object instance = injectionTarget.produce(creationalContext);
                injectionTarget.inject(instance, creationalContext);
                injectionTarget.postConstruct(instance);
                return instance;
            }

            @Override
            public void destroy(Object instance, CreationalContext creationalContext) {
                injectionTarget.preDestroy(instance);
                injectionTarget.dispose(instance);
                creationalContext.release();
            }

            @Override
            public Set<?> getTypes() {
                Set<Type> types = new HashSet<>();
                types.add(finalKlazz);
                types.add(Product.class);
                types.add(Object.class);
                return types;
            }

            @Override
            public Set getQualifiers() {
                Set<Annotation> qualifiers = new HashSet<Annotation>();
                qualifiers.add(new AnnotationLiteral<Default>() {
                });
                qualifiers.add(new AnnotationLiteral<Any>() {
                });
                return qualifiers;
            }

            @Override
            public Class getScope() {
                return ApplicationScoped.class;
            }

            @Override
            public String getName() {
                return "product";
            }

            @Override
            public Set getStereotypes() {
                return Collections.emptySet();
            }

            @Override
            public boolean isAlternative() {
                return false;
            }
        };

        CreationalContext ctx = bm.createCreationalContext(bean);
        Product produto = (Product) bm.getReference(bean, finalKlazz, ctx);
        return produto;
    }
}

bean到JSF页面:

package test;

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;

/**
 *
 * @author Welyab
 */
@Named
@RequestScoped
public class TestBean {

    @Inject
    @ProductProducer
    private Product product;

    public Product getProduct() {
        return product;
    }
}

使用bean的JSF页面的简单片段。

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
                template="/install/ayszu-template.xhtml"
                xmlns:p="http://primefaces.org/ui"
                xmlns:jsf="http://xmlns.jcp.org/jsf"
                xmlns:h="http://xmlns.jcp.org/jsf/html">
    <ui:define name="body">
        <form jsf:id="form" >
            <h:commandButton value="a" action="#{testBean.product.a}" />
            <h:commandButton value="b" action="#{testBean.product.b}" />
            <h:commandButton value="c" action="#{testBean.product.c}" />
        </form>
    </ui:define>
</ui:composition>

带有错误的堆栈跟踪[所有异常看起来都是由类转换异常引起的]

30-Dec-2014 18:59:37.944 WARNING [http-nio-8082-exec-24] com.sun.faces.lifecycle.InvokeApplicationPhase.execute #{testBean.product.c}: java.lang.ClassCastException: test.ProductImplWithGroovy cannot be cast to test.ProductImplWithGroovy
 javax.faces.FacesException: #{testBean.product.c}: java.lang.ClassCastException: test.ProductImplWithGroovy cannot be cast to test.ProductImplWithGroovy
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118)
    at javax.faces.component.UICommand.broadcast(UICommand.java:315)
call init()
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:301)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.ocpsoft.rewrite.servlet.RewriteFilter.doFilter(RewriteFilter.java:226)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.welyab.ayszu.core.MainFilter.doFilter(MainFilter.java:72)
    at com.welyab.ayszu.core.MainFilter.doFilter(MainFilter.java:67)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:136)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:74)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:516)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1015)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:652)
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1575)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1533)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: javax.faces.el.EvaluationException: java.lang.ClassCastException: test.ProductImplWithGroovy cannot be cast to test.ProductImplWithGroovy
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:101)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
    ... 35 more
Caused by: java.lang.ClassCastException: test.ProductImplWithGroovy cannot be cast to test.ProductImplWithGroovy
    at test.ProductImplWithGroovy$Proxy$_$$_WeldClientProxy.c(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.sun.el.parser.AstValue.invoke(AstValue.java:275)
    at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
    at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
    at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
    ... 36 more

30-Dec-2014 18:59:38.182 FATAL [http-nio-8082-exec-24] com.sun.faces.context.ExceptionHandlerImpl.log JSF1073: javax.faces.FacesException obtido durante o processamento de INVOKE_APPLICATION 5: UIComponent-ClientId=, Message=#{testBean.product.c}: java.lang.ClassCastException: test.ProductImplWithGroovy cannot be cast to test.ProductImplWithGroovy
30-Dec-2014 18:59:38.191 FATAL [http-nio-8082-exec-24] com.sun.faces.context.ExceptionHandlerImpl.log #{testBean.product.c}: java.lang.ClassCastException: test.ProductImplWithGroovy cannot be cast to test.ProductImplWithGroovy
 javax.faces.FacesException: #{testBean.product.c}: java.lang.ClassCastException: test.ProductImplWithGroovy cannot be cast to test.ProductImplWithGroovy
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:89)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:301)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.ocpsoft.rewrite.servlet.RewriteFilter.doFilter(RewriteFilter.java:226)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.welyab.ayszu.core.MainFilter.doFilter(MainFilter.java:72)
    at com.welyab.ayszu.core.MainFilter.doFilter(MainFilter.java:67)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:136)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:74)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:516)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1015)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:652)
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1575)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1533)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: javax.faces.FacesException: #{testBean.product.c}: java.lang.ClassCastException: test.ProductImplWithGroovy cannot be cast to test.ProductImplWithGroovy
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118)
    at javax.faces.component.UICommand.broadcast(UICommand.java:315)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    ... 31 more
Caused by: javax.faces.el.EvaluationException: java.lang.ClassCastException: test.ProductImplWithGroovy cannot be cast to test.ProductImplWithGroovy
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:101)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
    ... 35 more
Caused by: java.lang.ClassCastException: test.ProductImplWithGroovy cannot be cast to test.ProductImplWithGroovy
    at test.ProductImplWithGroovy$Proxy$_$$_WeldClientProxy.c(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.sun.el.parser.AstValue.invoke(AstValue.java:275)
    at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
    at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
    at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
    ... 36 more

0 个答案:

没有答案