2016-12-20 10 views
0

私は、MapStructを使用してエンティティをDTOに変換する作業を支援するマッパーを生成するmavenプロジェクトを持っています。 このマッパーは、Mavenのgenerate-sourcesフェーズで生成され、target/generated-sourcesおよびtarget/AppName/WEB-INF/classesフォルダーに格納されます。生成されたソースでウェルドルックアップクラスを作成する方法

例えば、私はこのマッパー

@Mapper 
public interface RuleMapper { 

    RuleDto ruletoDto(Rule rule); 

    //other cool stuf 
} 

を持って、私はそれが次を生成しますので、CDIを使用するMapStructを立体配置の:

@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作品、問題私はこのクラスのテストをjunitしようとしています。そのために、私は以下のようにカスタムランナーを実装しました:

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)いいえアペンダをロガーのために見つかりませんでしたWARN 。 log4j:WARN log4jシステムを適切に初期化してください。 log4j:WARN詳細については、http://logging.apache.org/log4j/1.2/faq.html#noconfigを参照してください。

ログに関する警告、および以下の例外:br.com.treinoos.common.cdi.WeldJUnit4Runner.createTestで

java.lang.ExceptionInInitializerError (WeldJUnit4Runner.java:15) 組織でorg.junit.runners.BlockJUnit4ClassRunner.methodBlockでorg.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) で.junit.runners.BlockJUnit4ClassRunner $ 1.runReflectiveCall(BlockJUnit4ClassRunner.java:266) ( BlockJUnit4ClassRunner.java:263) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit org.junit.runnersでorg.junit.runners.ParentRunner $ 3.run(ParentRunner.java:290) でorg.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) で4ClassRunner.java:78) .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)(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) at org。eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 原因:org.jboss.weld.exceptions.DeploymentException:WELD-001408:限定子@Defaultを使用したタイプRuleMapperの満たされていない依存性注入時に point [BackedAnnotatedField] @Inject private br.com.treinoos.model.core.business.treinoos.mappers.RuleMapperTest.ruleMapper br.com.treinoos.model.core.business.treinoos.mappers.RuleMapperTest.ruleMapper(RuleMapperTest。 (Validator.java:281) at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:359) at weld.bootstrap.Validator.validateGeneralBean(Validator.java:134) at org.jboss.weld.bootstrap.Validator.valid ateRIBean(Validator.java:155) at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:518) at 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 java.util.concurrent.FutureTask.runで(IterativeWorkerTaskFactory.java:56) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)で(FutureTask.java:266) で(java.lang.String) ng.Thread.run(Thread.java:745)

Like 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

'beans.xml'を' src/main/resources/META-INF'に追加しましたか? –

+0

@ジョーはい、しました。 –

+0

これはあなたがリストした内容とまったく同じですか?あなたはこれが明示的に 'src/test/resources'であることを言います。私のパスに注意してください - それは' src/main/webapp'ではない –

答えて

0

ここにあなたの問題の詳細な説明と、私が書いたことがそれを修正する理由があります。

Mavenには少なくとも2つのクラスローダーがあります。テストクラスパスとメインクラスパスにそれぞれ独自のクラスローダーがあります。依存関係の構造に応じて他のものを持つことができます。 CDIは、このように実行すると、各クラスローダーを別々のBeanアーカイブとして識別します。 src/main/webappは、明示的にWARファイル用です。 beans.xmlにはBeanアーカイブがありません。 src/main/resourcesに1を追加します。この問題は、溶接をインスタンス化する方法に固有です。

これを正しく行う他のプロジェクト - CDI-unitArquillian、特にWeld Embeddedコンテナがあります。これらのいずれかを使用する場合、これは問題ではありません。

+0

CDIUnitを使いましたが、問題がlibかどうか試してみました。とにかく、ありがとう、それは私を助けた。 –

関連する問題