2013-05-31 4 views
8

Ich habe eine Bibliothek, die als ausführbare JAR-Datei gebündelt und zu weblogic/tomcat classpath hinzugefügt wird, wie kann ich eine Hauptmethode aus der JAR-Datei ausführen, wenn der Server gestartet und geladen wird die Klassen aus der JAR-Datei.Bootstrap ausführbare JAR-Datei im Klassenpfad beim Start des Servers

was ich möchte, ist einige Initialisierungscode als erste Sache zu haben, wenn die JAR-Datei geladen ist und der Server ohne Benutzereingriff gestartet wird.

Hinweis: Ich weiß, ich kann mein Glas in einer Kriegsdatei bündeln, aber ich habe einen Aspekt Code in meiner Bibliothek, die ich alle laufenden Anwendungen in der JVM weben möchte, wenn ich mein Glas in War-Datei, das aspectj bündeln Code wird nur in die Klassen in der WAR-Datei einweben, also habe ich meine Bibliotheks-JAR-Datei in den Klassenpfad eingefügt.

Vielen Dank im Voraus.

Antwort

2

Die einfachste Möglichkeit ist die Bereitstellung eines trivialen Servlets in einer WAR-Datei, die auf Ihre JAR-Datei verweist. Das Servlet kann auf start up upon deployment/container start konfiguriert werden, und dann kann es die Klasse aufrufen, die Ihre main() Methode enthält.

+0

Ich habe einige aspectj Code in meiner Bibliothek, die ich alle laufenden Anwendungen in der jvm weben will, wenn ich mein Glas in Kriegsdatei bündeln, der Aspektj Code wird nur in die Klassen in der Kriegsdatei weben. – Sammy

+0

Raten Sie, dass diese Methode nicht funktioniert, da sie keine globalen Klassen oder Klassen in anderen WAR-Dateien instrumentiert. Bitte sehen Sie meine Lösung unten, wenn es passt. – Subhas

0

Da Anwendungsserver/Servlet-Container in der Regel viele verschiedene Klassenlader haben, benötigen Sie höchstwahrscheinlich eine andere Strategie zum Weben von Aspekten in Ihrem Code als in Standalone-Anwendungen.

Ich würde empfehlen, die Aspekte zu jeder Kriegsdatei hinzuzufügen, die zur Erstellungszeit bereitgestellt wird. Dies könnte einer üblichen Technik folgen - im Gegensatz zu einer serverspezifischen.

Weitere bin ich nicht sicher, dass es tatsächlich (ordnungsgemäß & unterstützt) auf einem Server durchgeführt werden kann. In der Regel wird ein Server erstellt, um alle Webapps voneinander zu trennen. Sie könnten es zum Funktionieren bringen, aber es könnte beim nächsten Update des Servers brechen.

Es könnte einfacher sein, eine alternative Technik vorzuschlagen, wenn Sie das Problem angeben, das Sie mit Ihrem vorgeschlagenen Ansatz lösen möchten.

Bearbeiten Sie nach Ihrem Kommentar: Betrachten Sie den Standardlebenszyklus der Webanwendung: Sie können Code ausführen, z. in einem Servlet, nachdem es bereitgestellt wurde. Wenn Sie darauf bestehen, dass Ihr Code in main enthalten ist, können Sie diese Methode aus dem Initialisierungscode Ihrer Webanwendung aufrufen.

+0

Ich schreibe ein Leistungsüberwachungs - Tool, das an unsere Geschäftsanforderungen angepasst ist, und ich würde gerne alle Anwendungen überwachen können, ohne das Jar in jede Kriegsdatei zu integrieren. Bis jetzt funktioniert es großartig, indem es alle Aspekte bündelt benötigte Abhängigkeiten in einer JAR-Datei und fügte sie dem Klassenpfad des Servers hinzu (Weblogic und Tomcat für den Moment), konnte ich mich in alle Anwendungen einarbeiten, die auf der JVM implementiert waren. aber ich muss noch etwas Initialisierungscode von der JAR-Datei ausführen, wenn es geladen wird, ohne die anderen Anwendungen ändern zu müssen – Sammy

+0

... so war die Absicht der Frage, einen Initialisierungscode zu haben, der aus dem jar ausführt Initialisierung benötigt für die Aspekte. – Sammy

+0

Das einzige Problem mit dem vorgeschlagenen Ansatz ist, dass das jar mit dem Aspekt vor jeder Webanwendung geladen werden soll, daher könnte es zu spät sein, die Hauptmethode im Servlet aufzurufen. – Sammy

5

eine Klasse in Ihrem JAR mit dem folgenden Code hinzufügen:

public class TomcatStartupListener implements org.apache.catalina.LifecycleListener { 
    public void lifecycleEvent(org.apache.catalina.LifecycleEvent event) { 
    if (event.getType().equals("after_start")) { 
     // call your main method here 
    } 
    } 
} 

Hinweis: Um dies zu kompilieren, müssen Sie <tomcat-dir>/lib/catalina.jar zu Ihrem Classpath hinzuzufügen. Andernfalls wird es beim Kompilieren nicht in der Lage sein, die notwendigen Schnittstellen zu finden (org.apache.catalina.LifecycleListener und org.apache.catalina.LifecycleEvent). Sobald Sie mit dem Kompilieren fertig sind, setzen Sie das JAR wie gewohnt unter <tomcat-dir>/lib.

jetzt offen <tomcat-dir>/conf/server.xml und fügen Sie den folgenden unter dem <Server> Abschnitt:

<Listener className="com.yourpackage.TomcatStartupListener" /> 

Nun, wenn Ihr Tomcat-Server startet, diese TomcatStartupListener Klasse in Ihrem JAR genannt wird, und Sie können Ihre Hauptmethode aufrufen. Es gibt auch viele andere Event-Typen!Sie können jede dieser Ereignistypen verwenden:

  • before_init
  • after_init
  • before_start
  • configure_start
  • Start
  • after_start
  • before_stop
  • Anschlag
  • configure_stop
  • after_stop
  • before_destroy
  • after_destroy

Dieser Ansatz wegen der Art und Weise notwendig ist, die classloaders work in Tomcat (oder sogar die meisten JVMs). Hier sind die wichtigsten Punkte aus diesem Link:

There are three aspects of a class loader behavior 
    Lazy Loading 
    Class Caching 
    Separate Namespaces 

Die JVM sehr schwer bekommen, wenn alle Klassen innerhalb aller JAR-Dateien wahllos erhalten geladen. So werden die Klassen innerhalb gemeinsamer JARs nur on-demand geladen. Sie können die Hauptmethode nur aufrufen, indem Sie den obigen Lifecycle-Listener hinzufügen.

+0

Gibt es eine globale Lösung, die auf allen Anwendungsservern funktioniert, die nicht für Tomcat spezifisch ist? – Sammy

+0

Nein. Oracle verfügt über eigene APEX-Listener, und auf ähnliche Weise verfügt jeder Server über eigene Listener. J2EE definiert nur Listener für einen bestimmten Webkontext, es gibt keine Listener für einen gesamten Server an. Jeder Server hat also eine eigene Möglichkeit, serverweite Ereignisse zu überwachen. – Subhas

+0

Wenn Sie ein JAR erstellen, dann ist es die Art, wie andere Bibliotheken es tun - haben Sie ** TWO JARs **. Einer ist dein Haupt JAR. Zweitens ist eine serverspezifische * Listener JAR *, die nur die Listener-Klasse hat. z.B. Für Tomcat würden Sie den obigen Code in einem 'yourapp-tomcat.jar' haben, und für Oracle hätten Sie einen anderen Code in' yourapp-oracle.jar'.Erlauben Sie den Benutzern dann, die jeweils zusätzliche Listener-JAR zu verwenden, die dem von ihnen verwendeten Anwendungsserver entspricht. – Subhas

0

Sie müssen einen Java-Agenten registrieren. Siehe diesen Link: java.lang.instrument.

java.lang.instrument bietet Dienste, mit denen Java-Programmiersprachenagenten Programme programmieren können, die auf der JVM ausgeführt werden.

Dies ist der richtige Weg, dies zu tun.