Как запустить класс в WAR из командной строки?
У меня есть класс Java, который имеет основную структуру, и я использовал ее как автономное приложение из командной строки, например.
java -jar myjar.jar params
Мне нужно было переупаковать код для запуска под apache, и весь мой код, включая класс точки входа из старой банки, попал в файл WAR, чтобы легко вставить его в веб-сервер.
Тем не менее, я все еще хочу иметь возможность запускать его из командной строки, и код не изменился и все там, я просто не могу понять, как его запустить.
Вот что я пробовал...
Я предполагал, что WAR была похожа на банку, поэтому
java -jar mywar.war params
Не получилось сказать, что в манифесте не было никакого основного класса.
Я вручную добавил манифест к войне и снова попытался с тем же эффектом.
Я заметил, что в моей войне у меня была папка с именем META-INF, содержащая файл manifest.mf, поэтому я добавил строку к объявлению моего основного класса, как и к нормальному манифесту...
Manifest-Version: 1.0
Main-Class: mypackage.MyEntryPointClass
Это дало noClassDefFoundError mypackage.MyEntryPointClass
, что является прогрессом. Это заставило меня поверить, что это был просто путь, поэтому я попробовал
Manifest-Version: 1.0
Main-Class: WEB-INF.classes.mypackage.MyEntryPointClass
Теперь я получаю ту же ошибку, но с трассировкой стека...
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)
Я немного искал Google, но не могу найти ничего, что отвечает на мой вопрос, и я прочитал здесь несколько других вопросов, которые немного отличаются друг от друга, поэтому я думал, что отправлю.
Java 1.5, а не то, что я думаю, что это должно иметь значение.
Ответы
Ответ 1
Вы можете сделать то, что Hudson (проект непрерывной интеграции).
вы загружаете войну, которую можно развернуть в tomcat или выполнить с помощью
java -jar hudson.war
(Поскольку у него встроенный двигатель Jetty, запуск его из командной строки приводит к запуску сервера.) В любом случае, посмотрев на манифест hudson, я понимаю, что они помещают основной класс в корневой каталог для архива. В вашем случае ваш военный макет должен выглядеть следующим образом:
под root:
- mypackage/MyEntryPointClass.class
- WEB-INF/lib
- WEB-INF/классы
- META-INF/MANIFEST.MF
в то время как манифест должен содержать следующую строку:
Main-Class: mypackage.MyEntryPointClass
обратите внимание, что mypackage/MyEntryPointClass.class доступен только из командной строки, а классы под WEB-INF/классами доступны только с сервера приложений.
НТН
Ответ 2
Война - это webapp. Если вы хотите, чтобы консольное/автономное приложение повторно использовало те же классы, что и webapp, рассмотрите возможность упаковки ваших общих классов в банке, которую вы можете поместить в WEB-INF/lib
. Затем используйте эту банку из командной строки.
Таким образом, вы получаете как консольное приложение, так и вы можете использовать одни и те же классы в своих сервлетах, не создавая двух разных пакетов.
Это, конечно, верно, когда война взорвалась.
Ответ 3
Чтобы выполнить SomeClass.main(String [] args) из развернутого файла войны, выполните:
Шаг 1: Создать класс SomeClass.java, который имеет метод основных методов, то есть (public static void main (String [] args) {...})
Шаг 2: Разверните свою WAR
Шаг 3: cd/usr/local/yourprojectsname/tomcat/webapps/projectName/WEB-INF
Шаг 4: java -cp "lib/jar1.jar: lib/jar2.jar:...: lib/jarn.jar" com.mypackage.SomeClass arg1 arg2... arg3
Примечание1: (чтобы узнать, находится ли класс SomeOtherClass.class в /usr/tomcat/webapps/projectName/WEB -INF/lib)
run → cd/usr/tomcat/webapps/projectName/WEB-INF/lib && &
найти. -name '*.jar' | при чтении jarfile; do if jar tf "$ jarfile" | grep SomeOtherClass.class; затем echo "$ jarfile"; Fi; сделано
Примечание2: напишите на стандарт, чтобы вы могли видеть, работает ли ваш основной файл с помощью операторов печати на консоли. Это называется задней дверью.
Примечание3: Комментарий, высказанный Божидаром Божановым, кажется правильным
Ответ 4
Правила размещения классов в архиве - это то, что расположение объявления пакета файла и расположение файла в архиве должны совпадать. Поскольку ваш класс находится в WEB-INF/классах, он считает, что класс недействителен для запуска в текущем контексте.
Единственный способ сделать то, что вы просите, - переупаковать войну, чтобы файл .class
находился в каталоге mypackage
в корневом каталоге архива, а не в каталоге WEB-INF/classes. Однако, если вы это сделаете, вы больше не сможете получить доступ к файлу с любого из своих веб-классов.
Если вы хотите повторно использовать этот класс как в войне, так и снаружи из командной строки java, подумайте о создании исполняемого банку, который вы можете запустить из командной строки, а затем помещаете эту банку в файл war
WEB-INF/lib каталог.
Ответ 5
Как и то, что Ричард Детч, но с немного легче следовать (также работает с пакетами)
Шаг 1. Разверните файл войны.
jar -xvf MyWar.war
Шаг 2: перейдите в каталог
cd WEB-INF
Шаг 3: Запустите главную страницу со всеми зависимыми элементами
java -classpath "lib/*:classes/." my.packages.destination.FileToRun
Ответ 6
В Maven проект, вы можете создать банку автоматически, используя Maven War, установив archiveClasses
в true
. Пример ниже.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<archiveClasses>true</archiveClasses>
</configuration>
</plugin>
Ответ 7
Если вы используете Maven, просто следуйте документации maven-war-plugin
о Как создать JAR, содержащий классы в моем webapp? ": добавить <attachClasses>true</attachClasses>
в <configuration>
плагина:
<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>
У вас будет 2 продукта в папке target/
:
- Сам
project.war
-
project-classes.jar
, который содержит все скомпилированные классы в банке
Затем вы сможете выполнить основной класс с использованием классического метода: java -cp target/project-classes.jar 'com.mycompany.MainClass' param1 param2
Ответ 8
Хорошо, согласно Wikipedia, с файлом WAR, классы, которые загружаются в путь к классам, находятся в разделе "/WEB -INF/classes" и "/WEB-INF/lib".
Вы можете попробовать просто поместить копию классов в корневую файловую систему zip файла (что и является войной/банкой). Я не уверен, что это сработает.
Вы всегда можете просто создать два отдельных файла.
Ответ 9
Невозможно запустить класс java из WAR файла. Файлы WAR имеют другую структуру для файлов Jar.
Чтобы найти связанные классы java, экспортируйте (предпочтительный способ использования ant), поскольку Jar поместил его в свой веб-приложение lib.
Затем вы можете использовать файл jar как обычно для запуска java-программы. Тот же банку также упоминался в веб-приложении (если вы положили эту банку в веб-приложение lib)