2013-05-12 1 views
6

Problema: Scansione di annotazione del componente a molla che non rileva la classe annotata nel contenitore esterno non inclusa in pom.xml. Ma ho bisogno di cercare classi con annotazioni specifiche da giare esterne. Questi jar esterni verranno posizionati nel classpath ma non saranno noti alla mia applicazione durante la compilazione.Scansione di annotazione non scansionare giare esterne nel classpath

1) Abbiamo un modulo maven (artifactId = "metric_processor") che produce un file jar (metric_processor.jar) ed ha seguenti classi

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 { 
    ..... 
} 

2) Abbiamo un altro modulo Maven ("artifactId = "metric_processor_external"), che produce un barattolo (metric_processor_external.jar) e comprende modulo "metric_processor" come portata fase di compilazione.

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

3) Abbiamo un terzo (principale) modulo maven (artifactId = "main_application"), che è un'applicazione stand-alone (usa molla) che include es modulo "metric_processor" in ambito di compilazione. (Ma non include "metric_processor_external"). Il plugin di generazione per il terzo modulo è

<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> 

Application contesto XML per questo modulo è

<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> 

devo classe a seguito della quale è il punto di partenza dell'applicazione

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()); 
     } 
    } 
} 

siamo compilare il terzo modulo come

maven clean install assembly:single 

Questo produce il file jar "main_application-con-dependencies.jar"

Poi abbiamo fatto il suo come

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

Adesso l'applicazione trova solo "LatencyMetricProcessor" e non trova il "TestMetricProcessor".

Qualcuno può aiutare?

+0

usiamo primavera 2.5.6 – Thiyanesh

risposta

8

Quando si utilizza l'opzione -jar per eseguire un file jar, l'opzione -cp viene ignorata.

Il Oracle Java docs per l'opzione -jar dicono:

-jar

eseguire un programma incapsulato in un file JAR. Il primo argomento è il nome di un file JAR invece del nome di una classe di avvio. Per fare in modo che l'opzione funzioni, il file manifest del file JAR deve contenere una riga del modulo Main-Class: classname. Qui, classname identifica la classe con il metodo statico void principale (String [] args) che funge da punto di partenza dell'applicazione. Vedere la pagina di riferimento dello strumento Jar e la traccia Jar del Java Tutorial per informazioni su come lavorare con i file Jar e manifesti file Jar.

Quando si utilizza questa opzione, il file JAR è la fonte di tutte le classi di utenti, e le altre impostazioni di percorso classe utente vengono ignorati.

Verificate anche questo post: stackoverflow.com/questions/5879925/in-linux-how-to-execute-java-jar-file-with-external-jar-files

quindi è necessario specificare il metric_process_external.jar nel file manifest con un colpo di testa Class-Path:. Dovresti essere in grado di ottenere il tuo plugin assembly Maven per farlo.

Se questo non è pratico, è necessario eseguire l'applicazione senza il flag -jar:

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

La ringrazio molto. Funziona bene. – Thiyanesh

+0

Cosa succede se sto usando la dichiarazione dei bean usando l'XML. Funzionerà? Sto affrontando problemi lì. – Shamli