2013-05-12 12 views
6

問題:Springコンポーネントの注釈スキャンで、pom.xmlに含まれていない外部jarでアノテートされたクラスが取得されない。しかし、私は外部のジャーから特定の注釈を持つクラスをスキャンする必要があります。これらの外部ジャーはクラスパスに配置されますが、コンパイル時には私のアプリケーションには知られません。注釈スキャンでクラスパス内の外部ジャーをスキャンしない

1)我々はJARファイル(metric_processor.jar)を生成し、有しMavenのモジュール(たartifactId = "metric_processor")以下のクラス

package com.metric; 
@Target({ElementType.TYPE}) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface ProcessMetric { 
    String name(); 
} 

package com.metric; 
public interface MetricProcessor { 
    int computeMetric(); 
} 

package com.metric; 
@ProcessMetric(name="LATENCY") 
@Component 
public class LatencyMetricProcessor implements MetricProcessor { 
    ..... 
} 
)我々は、(別のMavenのモジュールを持っているを持っている "たartifactId =ジャー(metric_processor_external.jar)を生成し、コンパイル時の範囲として "metric_processor" モジュールを含む) "metric_processor_external"。

package com.metric; 
@ProcessMetric(name="TEST_METRIC_EXTERNAL") 
@Component 
public class TestMetricProcessor implements MetricProcessor { 
    .... 
} 

3)我々は、第三の(主)Mavenのモジュール(たartifactId = "main_application" を有する)はスタンドアローンのアプリケーションです(春を使用します)。 esモジュール "metric_processor"をコンパイルスコープに追加します。 (しかし、 "metric_processor_external"は含まれません)。第3のモジュールのビルドプラグインは、このモジュールの

<build> 
    <plugins> 
     <plugin> 
      <artifactId>maven-assembly-plugin</artifactId> 
      <version>2.4</version> 
      <configuration> 
       <descriptorRefs> 
        <descriptorRef>jar-with-dependencies</descriptorRef> 
       </descriptorRefs> 
       <archive> 
        <manifest> 
         <mainClass>com.main.TriggerMetricProcessor</mainClass> 
        </manifest> 
       </archive> 
      </configuration> 
      <executions> 
       <execution> 
        <id>make-assembly</id> 
        <phase>package</phase> 
        <goals> 
         <goal>single</goal> 
        </goals> 
       </execution> 
      </executions> 
     </plugin> 
    </plugins> 
</build> 

アプリケーションコンテキストXMLは、私はアプリケーションの出発点は、我々

package com.main; 

import ... 

public class TriggerMetricProcessor { 
    public static void main(String[] args) throws Exception { 
     ApplicationContext context = 
       new ClassPathXmlApplicationContext("application-context.xml"); 

     TriggerMetricProcessor triggerMetricProcessor = (TriggerMetricProcessor) context.getBean("triggerMetricProcessor"); 
     triggerMetricProcessor.initMetricProcessor(context); 
    } 

    private void initMetricProcessor(ApplicationContext context) { 
     GenericBeanFactoryAccessor beanFactoryAccessor = new GenericBeanFactoryAccessor(context); 
     final Map<String, Object> metricProcessors = beanFactoryAccessor.getBeansWithAnnotation(ProcessMetric.class); 
     for (final Object metricProcessor : metricProcessors.values()) { 
      final Class<? extends MetricProcessor> metricProcessorClass = (Class<? extends MetricProcessor>)metricProcessor.getClass(); 
      final ProcessMetric annotation = metricProcessorClass.getAnnotation(ProcessMetric.class); 
      System.out.println("Found MetricProcessor class: " + metricProcessorClass + ", with name: " + annotation.name()); 
     } 
    } 
} 

ある以下のクラスを持っている

<beans> 
     <context:component-scan base-package="com.metric"> 
      <context:include-filter type="annotation" expression="com.metric.ProcessMetric" /> 
     </context:component-scan> 
     <bean id="triggerMetricProcessor" class="com.main.TriggerMetricProcessor" /> 
    </beans> 

です第3のモジュールを

maven clean install assembly:single 
としてコンパイルします。

これは

をjarファイル "main_application-と-dependencies.jar" を生成その後、我々は

java -cp "metric_process_external.jar" -jar main_application-with-dependencies.jar 

としての実行これでアプリケーションは、唯一の "LatencyMetricProcessor" を見つけ、 "TestMetricProcessor" が見つかりません。

誰かが助けてくれますか?

+0

我々が使用する春2.5.6 – Thiyanesh

答えて

8

-jarオプションを使用してjarファイルを実行すると、-cpオプションは無視されます。

-jarオプションのOracle Java docsは言う:

-jar

は、JARファイルにカプセル化されたプログラムを実行します。最初の引数は、起動クラス名の代わりに というJARファイルの名前です。 このオプションを機能させるには、JARファイルのマニフェストにMain-Class:classnameという形式の行 が含まれていなければなりません。ここで、classnameは、 がアプリケーションの開始点となるpublic static void main(String [] args)メソッドを持つ クラスを示します。 JarファイルとJARファイルマニフェストの操作に関する詳細は、 のJarツール リファレンスページとJavaチュートリアルのJarトレールを参照してください。

このオプションを使用すると、JARファイルはすべてのユーザー クラスのソースになり、他のユーザークラスのパス設定は無視されます。

また、この記事をチェックアウト:stackoverflow.com/questions/5879925/in-linux-how-to-execute-java-jar-file-with-external-jar-files

だから、Class-Path:ヘッダーを使用して、マニフェストファイルでmetric_process_external.jarを指定する必要があります。これを行うにはMavenアセンブリプラグインを入手できるはずです。

それは実用的ではない場合、あなたは-jarフラグなしでアプリケーションを実行する必要があります:

java -cp "metric_process_external.jar:main_application-with-dependencies.jar" com.main.TriggerMetricProcessor 
+0

はどうもありがとうございました。それはうまく動作します。 – Thiyanesh

+0

XMLを使用してBean宣言を使用している場合はどうなりますか?それは働くでしょうか?私はそこに問題に直面しています。 – Shamli

関連する問題