Ich habe eine Java-Klasse mit einer Hauptklasse und habe sie früher als eigenständige App über die Befehlszeile ausgeführt, z
java -jar myjar.jar params
Ich musste den Code neu packen, um unter Apache ausgeführt zu werden, und mein gesamter Code, einschließlich der Einstiegspunktklasse aus dem alten JAR, wurde zur einfachen Bereitstellung auf dem Webserver in einer WAR-Datei gespeichert.
Ich möchte es jedoch weiterhin über die Befehlszeile ausführen können, und der Code hat sich nicht geändert und ist alles enthalten. Ich kann nur nicht herausfinden, wie ich es zum Laufen bringen kann.
Folgendes habe ich versucht ...
Ich nahm an, dass der KRIEG wie ein Glas war
java -jar mywar.war params
Das scheiterte daran zu sagen, dass im Manifest keine Hauptklasse definiert war.
Ich habe dem Krieg manuell ein Manifest hinzugefügt und es erneut versucht, mit dem gleichen Effekt.
Ich bemerkte, dass ich in meinem Krieg einen Ordner namens META-INF hatte, der eine manifest.mf enthielt, also fügte ich eine Zeile hinzu, in der meine Hauptklasse wie in einem normalen Manifest deklariert wurde ...
Manifest-Version: 1.0
Main-Class: mypackage.MyEntryPointClass
Dies ergab noClassDefFoundError mypackage.MyEntryPointClass
eine Art Fortschritt. Das ließ mich glauben, dass es nur ein Pfadproblem war, also versuchte ich es
Manifest-Version: 1.0
Main-Class: WEB-INF.classes.mypackage.MyEntryPointClass
Ich bekomme jetzt den gleichen Fehler, aber mit einem Stack-Trace ...
Exception in thread "main" java.lang.NoClassDefFoundError: WEB-INF/classes/mypackage/MyEntryPointClass (wrong name: mypackage/MyEntryPointClass)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
Ich habe ein bisschen gegoogelt, kann aber nichts finden, was meine Frage beantwortet, und ich habe hier ein paar andere Fragen gelesen, die etwas anders sind, also dachte ich, ich würde etwas posten.
Java 1.5, nicht dass ich denke, dass das einen Unterschied machen sollte.
Antworten:
Ähnlich wie Richard Detsch, aber etwas einfacher zu befolgen (funktioniert auch mit Paketen)
Schritt 1: Packen Sie die War-Datei aus.
Schritt 2: Wechseln Sie in das Verzeichnis
Schritt 3: Führen Sie Ihr main mit allen Abhängigkeiten aus
java -classpath "lib/*:classes/." my.packages.destination.FileToRun
quelle
: -> ;
so dass der obige Befehljava -classpath "lib/*;classes/." my.packages.destination.FileToRun
speziell geändert wirdSie können das tun, was Hudson (Continuous Integration Project) tut. Sie laden einen Krieg herunter, der in Tomcat bereitgestellt oder mit ausgeführt werden kann
(Da es eine eingebettete Jetty-Engine hat, wird durch Ausführen über die Befehlszeile ein Server gestartet.) Wenn ich mir das Hudson-Manifest anschaue, verstehe ich, dass sie eine Hauptklasse im Stammverzeichnis für das Archiv ablegen. In Ihrem Fall sollte Ihr Kriegslayout folgendermaßen aussehen:
unter der Wurzel:
während das Manifest die folgende Zeile enthalten sollte:
Bitte beachten Sie, dass auf mypackage / MyEntryPointClass.class nur über die Befehlszeile zugegriffen werden kann und auf die Klassen unter WEB-INF / classes nur über den Anwendungsserver zugegriffen werden kann.
HTH
quelle
Ein Krieg ist eine Webapp. Wenn Sie möchten, dass eine Konsole / eigenständige Anwendung dieselben Klassen wie Ihre Webanwendung wiederverwendet, sollten Sie Ihre freigegebenen Klassen in eine JAR-Datei packen, die Sie einfügen können
WEB-INF/lib
. Verwenden Sie dann das Glas über die Befehlszeile. Auf diese Weise erhalten Sie beide Konsolenanwendungen und können dieselben Klassen in Ihren Servlets verwenden, ohne zwei verschiedene Pakete zu erstellen. Dies gilt natürlich, wenn der Krieg explodiert.quelle
Um SomeClass.main (String [] args) aus einer bereitgestellten Kriegsdatei auszuführen, gehen Sie wie folgt vor:
Schritt 1: Schreiben Sie die Klasse SomeClass.java mit einer Hauptmethodenmethode, dh (public static void main (String [] args) {...})
Schritt 2: Stellen Sie Ihr WAR bereit
Schritt 3: cd / usr / local / yourprojectsname / tomcat / webapps / projectName / WEB-INF
Schritt 4: java -cp "lib / jar1.jar: lib / jar2.jar: ...: lib / jarn.jar" com.mypackage.SomeClass arg1 arg2 ... arg3
Hinweis 1: (um festzustellen, ob sich die Klasse SomeOtherClass.class in / usr / tomcat / webapps / projectName / WEB-INF / lib befindet)
Führen Sie -> cd / usr / tomcat / webapps / projectName / WEB-INF / lib && find aus. -name '* .jar' | während gelesen jarfile; tun, wenn jar tf "$ jarfile" | grep SomeOtherClass.class; dann echo "$ jarfile"; fi; erledigt
Hinweis 2: Schreiben Sie in Standard Out, damit Sie über print-Anweisungen an die Konsole sehen können, ob Ihr Main tatsächlich funktioniert. Dies nennt man eine Hintertür.
Anmerkung 3: Der obige Kommentar von Bozhidar Bozhanov scheint richtig zu sein
quelle
Die Regeln zum Auffinden von Klassen in einer Archivdatei lauten, dass der Speicherort der Paketdeklaration der Datei und der Speicherort der Datei im Archiv übereinstimmen müssen. Da sich Ihre Klasse in WEB-INF / classes befindet, ist die Ausführung der Klasse im aktuellen Kontext möglicherweise nicht gültig.
Die einzige Möglichkeit, das zu tun, was Sie verlangen, besteht darin, den Krieg neu zu packen, sodass sich die
.class
Datei immypackage
Verzeichnis im Stammverzeichnis des Archivs und nicht im Verzeichnis WEB-INF / classes befindet. In diesem Fall können Sie jedoch von keiner Ihrer Webklassen mehr auf die Datei zugreifen.Wenn Sie diese Klasse sowohl im Krieg als auch außerhalb der Java-Befehlszeile wiederverwenden möchten, sollten Sie eine ausführbare JAR-
war
Datei erstellen, die Sie über die Befehlszeile ausführen können, und diese JAR- Datei dann in das Verzeichnis WEB-INF / lib der Datei einfügen.quelle
Wenn Sie Maven verwenden, folgen Sie einfach der
maven-war-plugin
Dokumentation über „ Wie erstelle ich eine JAR - Klassen in meinem Webapp enthalten? “: Add<attachClasses>true</attachClasses>
auf die<configuration>
des Plug - ins:<project> ... <artifactId>mywebapp</artifactId> <version>1.0-SNAPSHOT</version> ... <build> <plugins> <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.6</version> <configuration> <attachClasses>true</attachClasses> </configuration> </plugin> </plugins> </build> ... </project>
Sie haben 2 Produkte im
target/
Ordner:project.war
selbstproject-classes.jar
enthält alle kompilierten Klassen in einem GlasDann können Sie eine Hauptklasse mit der klassischen Methode ausführen:
java -cp target/project-classes.jar 'com.mycompany.MainClass' param1 param2
quelle
In Maven - Projekt können Sie jar bauen automatisch mit Maven War Plugin , indem Sie
archiveClasses
auftrue
. Beispiel unten.<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <configuration> <archiveClasses>true</archiveClasses> </configuration> </plugin>
quelle
Der beste Weg, wenn Sie Spring Boot verwenden, ist:
1 / ServletInitializer erstellen erweitert die SpringBootServletInitializer- Klasse. Mit der Methode konfigurieren Sie, welche Ihre Anwendungsklasse ausführen
2 / Generieren Sie immer eine Maven-Installations- WAR- Datei
3 / Mit diesem Artefakt können Sie sogar:
. start application from war file with java -jar file.war . put your war file in your favorite Web App server (like tomcat, ...)
quelle
Laut Wikipedia befinden sich die Klassen, die in den Klassenpfad geladen werden, mit einer WAR-Datei im Verzeichnis "/ WEB-INF / classes" und "/ WEB-INF / lib".
Sie können versuchen, einfach eine Kopie der Klassen in das Root-Dateisystem der Zip-Datei zu stellen (was ein War / Jar ist). Ich bin mir nicht sicher, ob das funktionieren würde.
Sie können immer nur zwei separate Dateien erstellen.
quelle
Es ist nicht möglich, eine Java-Klasse aus einer WAR-Datei auszuführen. WAR-Dateien haben eine andere Struktur als Jar-Dateien.
Um die zugehörigen Java-Klassen zu finden, exportieren Sie sie (bevorzugte Methode zur Verwendung von ant), wie Jar sie in Ihre Web-App-Bibliothek einfügt.
Dann können Sie die JAR-Datei wie gewohnt verwenden, um das Java-Programm auszuführen. Das gleiche Glas wurde auch in der Web-App verwendet (wenn Sie dieses Glas in die Web-App lib einfügen).
quelle