2016-12-20 71 views
0

我有一個maven項目,我使用MapStruct生成映射器以幫助將實體轉換爲DTO,反之亦然。 這個映射器是在maven的generate-sources階段生成的,並存儲在target/generated-sources和target/AppName/WEB-INF/classes文件夾中。如何在生成的源代碼上生成焊接查找類

例如,我有這樣的映射

@Mapper 
public interface RuleMapper { 

    RuleDto ruletoDto(Rule rule); 

    //other cool stuf 
} 

我可配置MapStruct使用CDI,所以它會產生如下:

@Generated(
value = "org.mapstruct.ap.MappingProcessor", 
date = "2016-12-19T23:19:36-0200", 
comments = "version: 1.1.0.CR1, compiler: javac, environment: Java 1.8.0_112" 
) 
@Singleton 
@Named 
public class RuleMapperImpl implements RuleMapper { 

    @Override 
    public RuleDto ruletoDto(Rule rule) { 

     ruleDto ruleDto = new ruleDto(); 

     if (rule != null) { 
      ruleDto.setIdRule(rule.getIdRule()); 
     } 

     return ruleDto; 
    } 
} 

Wildfly服務器上運行時,它的工作原理perfectely,問題是我正在努力測試這個班級,爲此,我實施了一個自定義亞軍,如下所示:

import org.junit.runners.BlockJUnit4ClassRunner; 
import org.junit.runners.model.InitializationError; 

public class WeldJUnit4Runner extends BlockJUnit4ClassRunner { 

    public WeldJUnit4Runner(Class<Object> clazz) throws InitializationError { 
     super(clazz); 
    } 

    @Override 
    protected Object createTest() throws Exception { 
     final Class<?> test = getTestClass().getJavaClass(); 
     return WeldContext.INSTANCE.getBean(test); 
    } 

} 

和:

import org.jboss.weld.environment.se.Weld; 
import org.jboss.weld.environment.se.WeldContainer; 

public class WeldContext { 

    public static final WeldContext INSTANCE = new WeldContext(); 

    private final Weld weld; 
    private final WeldContainer container; 

    private WeldContext() { 
     this.weld = new Weld(); 
     this.container = weld.initialize(); 
     Runtime.getRuntime().addShutdownHook(new Thread() { 
      @Override 
      public void run() { 
       weld.shutdown(); 
      } 
     }); 
    } 

    public <T> T getBean(Class<T> type) { 
     return container.instance().select(type).get(); 
    } 

} 

這些實現從here拍攝。

最後,測試:

@RunWith(WeldJUnit4Runner.class) 
public class RuleMapperTest { 

    @Inject 
    private RuleMapper ruleMapper; 

    @Test 
    public void coolTestName() { 
     Assert.assertTrue(Boolean.TRUE); 
    } 
} 

當我嘗試運行,這是控制檯輸出:

的log4j:警告沒有附加目的地可以發現記錄器(org.jboss.logging) 。 log4j:WARN請正確初始化log4j系統。 log4j:WARN有關更多信息,請參閱http://logging.apache.org/log4j/1.2/faq.html#noconfig

警告有關日誌,但以下情況除外:

java.lang.ExceptionInInitializerError 在br.com.treinoos.common.cdi.WeldJUnit4Runner.createTest(WeldJUnit4Runner.java:15) 在組織.junit.runners.BlockJUnit4ClassRunner $ 1.runReflectiveCall(BlockJUnit4ClassRunner.java:266) 在org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 在org.junit.runners.BlockJUnit4ClassRunner.methodBlock( BlockJUnit4ClassRunner.java:263) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit 4ClassRunner.java:78) 在org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 在org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:290) 在org.junit.runners .ParentRunner $ 1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:58) 在org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.eclipse.jdt.internal.junit4.runner。 JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 。eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 原因:org.jboss.weld.exceptions.DeploymentException:WELD-001408:類型RuleMapper帶有限定符的不滿意依賴關係@Default 注入時point [BackedAnnotatedField] @Inject private br.com.treinoos.model.core.business.treinoos.mappers.RuleMapperTest.ruleMapper at br.com.treinoos.model.core.business.treinoos.mappers.RuleMapperTest.ruleMapper(RuleMapperTest。的java:0) 在org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:359) 在org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:281) 在org.jboss。 weld.bootstrap.Validator.validateGeneralBean(Validator.java:134) at org.jboss.weld.bootstrap.Validator.valid在org.jboss.weld.bootstrap.ConcurrentValidator $ 1.doWork(ConcurrentValidator.java:68) org.jboss.weld.bootstrap.ConcurrentValidator $ 1.doWork(ConcurrentValidator.java:66) at org.jboss.weld.executor.IterativeWorkerTaskFactory $ 1.call(IterativeWorkerTaskFactory.java:63) at org.jboss.weld.executor .IterativeWorkerTaskFactory $ 1.call(IterativeWorkerTaskFactory.java:56) 在java.util.concurrent.FutureTask.run在(FutureTask.java:266) 在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617) at java.la ng.Thread.run(Thread.java:745)

像Weld不能查找生成的類。 的beans.xml已經src/test/resources/META-INF/beans.xml下創建:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
        http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" 
    version="1.1" bean-discovery-mode="all"> 
</beans> 

任何人都可以點我解決這個問題呢?我已經搜索了一些simillar,但沒有成功。

+0

你還給'src/main/resources/META-INF'添加了一個'beans.xml'嗎? –

+0

@Joh是的,我做到了。 –

+0

與列出的內容完全相同嗎?你提到這一個明確'src /測試/資源'也請注意我的路徑 - 它不是'src/main/webapp' –

回答

0

下面是對您的問題的完整說明,以及爲什麼我寫的修復了它。

在Maven中,您至少有2個類加載器。你的測試類路徑和主類路徑都有自己的類加載器。您可以根據您的依賴性結構獲得其他人。當以這種方式運行時,CDI將每個類加載器標識爲單獨的bean存檔。 src/main/webapp明確用於您的WAR文件。那裏的beans.xml沒有給你一個bean檔案。添加一個到src/main/resources呢。這個問題特定於你如何實例化焊接。

還有其他項目正確地做到這一點 - CDI-unitArquillian,特別是Weld Embedded容器。如果你使用其中之一,這不會是一個問題。

+0

我用CDIUnit,我改變嘗試看看問題是否是lib。無論如何,謝謝,這幫助了我。 –