Avere più classi principali in un progetto Java?

5

Supponiamo di possedere un codice Java e voglio essere in grado di eseguire più attività basate su questa stessa base:

  1. Esegui un server Web Jetty incorporato.
  2. Esegui un'inizializzazione una tantum del database (creazione, seed, ecc.)
  3. Esegui un'operazione di manutenzione programmata da cron (pulizia, backup, ecc.)
  4. Forse di più ...

Stavo pensando di costruire più jar autonomi, ognuno compilato con la stessa base, ma con diversi punti di ingresso principali. Penso che funzionerebbe, ma mi sono sentito un po 'ridondante. Questi jar contengono fondamentalmente le stesse cose, se non a causa delle diverse classi principali.

Non ho familiarità con Java. Esiste un modo standard per fare queste cose in Java? Cosa ne pensi dell'approccio che ho citato sopra?

    
posta Andree 09.05.2016 - 14:59
fonte

4 risposte

5

Grazie per tutte le ottime risposte, ma ho deciso di adottare un approccio di sottocomando, simile a quello adottato da git: git checkout ... git pull ... .

Quindi nel mio caso, avrei qualcosa di simile a questo:

java -jar MyApplication.jar server
java -jar MyApplication.jar db:seed
java -jar MyApplication.jar db:backup

Un'implementazione ingenua sarebbe probabilmente simile a qualcosa che segue le seguenti linee:

public class Launcher {

    public static void main(String... args) {

        if ("server".equals(args[0]) {
            new ServerCommand(args).run();
        }

        if ("db:seed".equals(args[0]) {
            new DataSeedCommand(args).run();
        }

        ...
    }
}

Il framework Dropwizard supporta già questo modello fuori dalla scatola con la nozione di Command . Hanno un comando predefinito server e i comandi personalizzati possono essere registrati tramite hook ( ref).

    
risposta data 10.05.2016 - 01:24
fonte
5

Raccomando di non utilizzare i jar eseguibili in questo caso. Probabilmente riuscirai a semplificare la vita e la vita delle persone che gestiscono la tua applicazione creando script per ogni cosa che desideri eseguire sulla riga di comando. Otterrà lo stesso risultato ed è più trasparente e flessibile rispetto all'utilizzo di jar eseguibili. Spesso quando incontro un jar eseguibile, lo aprirò, estrarrò la main-class dal manifest e costruirò uno script. Utilizzerei l'opzione jar eseguibile solo in casi molto semplici.

Se sei deciso a utilizzare i jar eseguibili, puoi creare un jar manifest-only che punta al jar contenente tutte le classi per evitare la duplicazione.

    
risposta data 09.05.2016 - 18:47
fonte
2

Non esiste uno standard reale. Penso che lo schema che stai suggerendo funzioni molto bene. Hai un codice base correlato e deliverable da gestire. Al momento sto facendo qualcosa di simile in cui una webserivce genera un processo Java. Fornisco semplicemente il file jar one e quando si esegue come servizio web, il processo forked sta semplicemente richiamando Java con lo stesso classpath / jar file ma un diverso entry point.

Per semplificarti la vita, potresti fornire insieme al tuo file .jar uno script di shell che prende argomenti e determina quale classe / metodo principale chiamare. Quindi i tuoi clienti non devono preoccuparsi di quale pacchetto / classe invocare e puoi refactoring senza esporlo ai tuoi clienti.

Guardando di più alle tue particolari esigenze, tuttavia, il tuo servizio web gestisce il tuo database e, in quanto tale, causerà confusione nel fatto che gli eseguibili separati modificano direttamente il tuo database? Se è così, potresti voler estendere il tuo webservice per fornire queste funzioni di manutenzione, e semplicemente invocare sul tuo webservice tramite un semplice script shell / curl / wget.

    
risposta data 09.05.2016 - 17:40
fonte
1

Imho non ci sono standard per questo.

  • Il molo usa web.xml per trovare il servlet richiesto.
  • Il tuo JAR può contenere più classi con una funzione principale in ciascuna.

Nella classe MANIFEST della JAR una è impostata come predefinita e verrà avviata da java -jar myprog.jar . Qualsiasi altra classe principale può essere avviata da java -cp myprog.jar my.package.Scheduler .

Potresti essere interessato a CLI di Apache Commons per creare una linea di comando real interfaccia.

    
risposta data 09.05.2016 - 15:24
fonte

Leggi altre domande sui tag