org.jboss.classfilewriter.DuplicateMemberException

org.jboss.classfilewriter.DuplicateMemberException

在 Wildfly 上部署我的应用程序时出现以下错误:

17:28:25,571 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-3) MSC000001: Failed to start service jboss.deployment.unit."Restaurant-1.1-SNAPSHOT.war".WeldStartService: org.jboss.msc.service.StartException in service jboss.deployment.unit."Restaurant-1.1-SNAPSHOT.war".WeldStartService: Failed to start service
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1904)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.jboss.weld.exceptions.WeldException: WELD-001524: Unable to load proxy class for bean Managed Bean [class com.naigoapps.restaurant.model.dao.RestaurantTableDao] with qualifiers [@Any @Default] with class class com.naigoapps.restaurant.model.dao.RestaurantTableDao using classloader ModuleClassLoader for Module "deployment.Restaurant-1.1-SNAPSHOT.war:main" from Service Module Loader
at org.jboss.weld.bean.proxy.ProxyFactory.getProxyClass(ProxyFactory.java:371)
at org.jboss.weld.injection.producer.SubclassedComponentInstantiator.createEnhancedSubclass(SubclassedComponentInstantiator.java:114)
at org.jboss.weld.injection.producer.SubclassedComponentInstantiator.initEnhancedSubclass(SubclassedComponentInstantiator.java:86)
at org.jboss.weld.injection.producer.SubclassedComponentInstantiator.<init>(SubclassedComponentInstantiator.java:79)
at org.jboss.weld.injection.producer.SubclassedComponentInstantiator.forInterceptedDecoratedBean(SubclassedComponentInstantiator.java:63)
at org.jboss.weld.injection.producer.BeanInjectionTarget.initializeAfterBeanDiscovery(BeanInjectionTarget.java:121)
at org.jboss.weld.injection.producer.InjectionTargetInitializationContext.initialize(InjectionTargetInitializationContext.java:42)
at org.jboss.weld.injection.producer.InjectionTargetService.initialize(InjectionTargetService.java:63)
at org.jboss.weld.bootstrap.WeldStartup.deployBeans(WeldStartup.java:433)
at org.jboss.weld.bootstrap.WeldBootstrap.deployBeans(WeldBootstrap.java:83)
at org.jboss.as.weld.WeldStartService.start(WeldStartService.java:95)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881)
... 3 more
Caused by: org.jboss.weld.exceptions.WeldException: Method  already exists. Method: getTargetClass Parameters:[] Return Type: Ljava/lang/Class;
at org.jboss.weld.bean.proxy.InterceptedSubclassFactory.addSpecialMethods(InterceptedSubclassFactory.java:386)
at org.jboss.weld.bean.proxy.InterceptedSubclassFactory.addMethods(InterceptedSubclassFactory.java:116)
at org.jboss.weld.bean.proxy.ProxyFactory.createProxyClass(ProxyFactory.java:469)
at org.jboss.weld.bean.proxy.ProxyFactory.getProxyClass(ProxyFactory.java:364)
... 15 more
Caused by: org.jboss.classfilewriter.DuplicateMemberException: Method  already exists. Method: getTargetClass Parameters:[] Return Type: Ljava/lang/Class;
at org.jboss.classfilewriter.ClassFile.addMethod(ClassFile.java:133)
at org.jboss.classfilewriter.ClassFile.addMethod(ClassFile.java:148)
at org.jboss.weld.bean.proxy.InterceptedSubclassFactory.addSpecialMethods(InterceptedSubclassFactory.java:378)
... 18 more

这些是我的源文件:

public interface Dao<E extends BaseEntity> {

    public Class<E> getTargetClass();
    public String getOrderByClause();

}


public abstract class AbstractDao<E extends BaseEntity> implements Dao<E>{

    [...]

    @Override
    public String getOrderByClause() {
        return null;
    }

}


public class RestaurantTableDao extends AbstractDao<RestaurantTable>{

    @Override
    public String getOrderByClause() {
        return "name";
    }

    @Override
    public Class<RestaurantTable> getTargetClass() {
        return RestaurantTable.class;
    }

}

抽象class和接口中定义的方法似乎有一些问题。 在添加 getOrderByClausegetTargetClass 这两个方法之前,问题没有发生

考虑到类型擦除,Weld 的 proxy classes 定义 getTargetClass() 方法以及相同的签名是巧合(或命运?)。

因此,如异常所述:

org.jboss.weld.exceptions.WeldException: 
Method  already exists.
Method: getTargetClass Parameters:[] Return Type: Ljava/lang/Class;

...并且因为这就是 Weld 必须工作和工作的方式,所以最安全、最简单和最快的方法就是重命名您的方法。

奖金: 如果您想知道代理到底是什么,这里有一篇来自 Stuart Douglas 的关于 Weld 的简短 article,它已经很老了,但仍然很重要。