ClassCastException与CDI生产者方法和来自脚本的groovy类
我正在学习Groovy语言以及将其与CDI集成的可能性 在java类路径中,有一个名为ClassCastException与CDI生产者方法和来自脚本的groovy类,groovy,jboss-weld,weld,Groovy,Jboss Weld,Weld,我正在学习Groovy语言以及将其与CDI集成的可能性 在java类路径中,有一个名为Product的接口。我创建了一个CDI生产者方法,该方法返回产品类型。 在另一个类中,我执行来自CDI生产者方法的产品的注入 在类路径之外,我用一个简单的groovy类编写了一个groovy脚本,用于实现产品接口 在CDI生产者方法中,我使用GroovyScriptEngine从脚本中检索类对象,以创建CDIBean 我正在使用 焊接版本2.2.8.1最终版作为CDI实施 Groovy版本2.3.9 Tom
Product
的接口。我创建了一个CDI生产者方法,该方法返回产品
类型。
在另一个类中,我执行来自CDI生产者方法的产品的注入
在类路径之外,我用一个简单的groovy类编写了一个groovy脚本,用于实现产品接口
在CDI生产者方法中,我使用GroovyScriptEngine
从脚本中检索类对象,以创建CDIBean
我正在使用
- 焊接版本2.2.8.1最终版作为CDI实施
- Groovy版本2.3.9
- Tomcat服务器7李>
- 同时使用JSF2.2.8李>
(认为问题只与CDI eh Groovy的Weld实现有关)
第一次一切都很好。可以在JSF页面中使用创建的bean,单击in按钮并在服务器端执行操作,然后在浏览器上刷新页面。groovy脚本类上所有声明的方法和字段都可以被访问并与JSF页面一起使用。CDI容器还执行对@PostConstruct
的调用。CDI生产者方法可以多次调用,并且所有的工作都可以进行
如前所述,第一时间一切正常。但是当groovy脚本更改时,会抛出一个ClassCastException
有人能帮我解决这个问题吗?这是焊接/沟槽问题,还是根本不可能
产品
界面:
package test;
/**
*
* @author Welyab
*/
@ProductMethodIntercetor
public interface Product {
public void a();
public void b();
}
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()";
}
}
实现产品
接口的groovy脚本:
package test;
/**
*
* @author Welyab
*/
@ProductMethodIntercetor
public interface Product {
public void a();
public void b();
}
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页面的一个简单片段
<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>
您是否也可以添加stacktrace/ExceptionAnk以便重播。我用stacktrace更新。我注意到,如果groovy类名更改,脚本重新加载就可以工作了。重新加载将生成一个新类。代理需要旧类并用于新实例,或者代理用于新类并用于旧实例。代码中似乎有东西在缓存代理。@WelyabPaula您是否需要使用GroovyScript引擎?Groovy的联合编译使这段代码成为simplerI第二个@blackdrag注释的方式。另外,我相信如果重新启动应用程序,ClassCastException
不会发生,因为类加载器中不会有productimpwithgroovy.class