2015-06-26 6 views
13

Desidero aggiungere un punto di ingresso alternativo alla mia applicazione Spring-Boot. Preferirei tenerlo come un barattolo di grasso. È possibile?Spring Boot - Come specificare una start-class alternativa? (Punti di ingresso multipli)

In base al loro documentation, la proprietà loader.main specifica il nome della classe principale da avviare.

Ho provato java -jar MyJar.jar --loader.main=com.mycompany.AlternateMain ma la classe iniziale specificata nel mio pom.xml era ancora in esecuzione (e se rimuovo questo dal pom.xml, allora errore durante la confezione).

In alternativa, ho provato java -cp MyJar.jar com.mycompany.AlternateMain ma non conosco un buon modo per aggiungere tutti i jar annidati al classpath.

Qualche suggerimento?

Edit: Ecco la soluzione che ho usato

Come jst suggerito, ho cambiato il mio programma di avvio per utilizzare il PropertiesLauncher. Ho fatto questo modificando la configurazione del mio plug-in maven-spring-boot.

<plugin> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-maven-plugin</artifactId> 
    <configuration> 
    <mainClass>${start-class}</mainClass> 
    <layout>ZIP</layout> 
    ... 

Il <layout>ZIP</layout>triggers Spring Boot to use the PropertiesLauncher.

ho creato il mio vaso di grasso (pacchetto mvn) allora si chiamava la principale alternativa in questo modo:

java -jar -Dloader.main=com.mycompany.AlternateMain MyJar.jar 

Grazie per l'aiuto!

+1

Spring Boot utilizza semplicemente il manifest di JAR per specificare la classe principale e il percorso di classe.Quindi penso che la vera domanda qui sia che ci può essere più di una Main Class in un JAR eseguibile? Questa domanda viene anche posta/risposta qui: http://stackoverflow.com/q/3976514/953327 – FGreg

+0

Cosa intendete realizzare con questo? Vuoi creare più applicazioni da Spring Boot? – Makoto

+0

@FGreg Posso accedere al principale alternativo usando il secondo comando che ho notato, che corrisponde alla risposta nel thread SO a cui si collega. Per poterlo utilizzare correttamente, dovrei capire come aggiungere i miei jar nidificati al classpath. –

risposta

8

Non credo che la proprietà si applichi nel tuo caso. Esistono 3 diversi "Launcher" (torna ai documenti e vedi). Se stai costruendo un vaso usa la classe JarLauncher. Se lo si passa a PropertiesLauncher, loader.main sarebbe utile.

META-INF/MANIFEST.MF

Main-Class: org.springframework.boot.loader.PropertiesLauncher 
+0

Sembra molto promettente, ma i miei risultati sono gli stessi. Per utilizzare PropertiesLauncher, ho configurato il plug-in spring-boot-maven, come descritto qui http://stackoverflow.com/a/21328440/2860319. Ho potuto vedere nel mio manifest che funzionava e il PropertiesLauncher era in uso, ma la proprietà loader.main specificata tramite la riga di comando non cambiava la classe iniziale ... hmmmm –

+0

Stavo aggiungendo le proprietà in modo errato, aggiornerò il mio post con quello che ho fatto. Grazie per l'ottimo suggerimento! –

3

Suggerirei di avere un singolo main ma utilizzando i profili Spring (o le proprietà di configurazione) per selezionare uno o l'altro "entry point" classe @Configuration.

+1

Puoi fornire un esempio, per favore? – rmv

7

ho preso un approccio diverso e utilizzare un parametro di riga di comando per determinare quale classe da utilizzare come mia classe SpringApplication. Ho solo un singolo metodo main(), ma diverse classi di applicazioni con diverse configurazioni che vengono utilizzate in base a un parametro della riga di comando.

ho una sola classe con un main() in esso:

public static void main(String[] args) { 
    SpringApplication app; 
    if(ArrayUtils.contains(args, "--createdb")){ 
     app = new SpringApplication(CreateDB.class); 
     args = (String[])ArrayUtils.add(args, "--spring.jpa.hibernate.ddl-auto=create"); 
    } else { 
     app = new SpringApplication(Application.class); 
    } 

    app.setWebEnvironment(false); 
    app.setShowBanner(false); 
    app.addListeners(new ConfigurationLogger()); 

    // launch the app 
    ConfigurableApplicationContext context = app.run(args); 

    // finished so close the context 
    context.close(); 
} 

Ma ho 2 diverse classi SpringApplication: Application.class & CreateDB.class. Ogni classe definisce un diverso percorso @ComponentScan e diverse opzioni @EnableAutoConfiguration e diverse opzioni @Configuration. Infine, in base ai miei argomenti della riga di comando, posso decidere se abilitare o meno profili aggiuntivi/ecc.

Nel mio caso, voglio un programma di avvio diverso per creare semplicemente lo schema DB e uscire, quindi ho forzato il parametro della riga di comando.

+0

Questo è il punto in cui stavo andando anch'io, presumibilmente 'CreateDB' e' Application' esistono in pacchetti separati, consentendo così di usare '@ ComponentScan' con' basePackages' impostato su quel pacchetto? – ben3000

+2

In effetti è possibile. Nel mio caso, sono effettivamente nello stesso pacchetto, ma il mio '@ComponentScan()' imposta diversi pacchetti base da analizzare con differenti regole di esclusione. Permette anche di avere diverse opzioni '@AutoConfiguration()', diverse classi di configurazione, ecc. E francamente - trovo molto più facile fare in questo modo che usare i parametri launcher e launcher per specificare nomi di classi lunghi; questo mi permette di astrarlo come voglio. Ho praticamente confezionato 2 app di SpringBoot separate (che condividono classi comuni) nello stesso barattolo. –