Как запустить class в WAR из командной строки?

У меня есть class Java, который имеет основную структуру, и я использовал для запуска как отдельное приложение из командной строки, например

java -jar myjar.jar params 

Мне нужно было переупаковать код для запуска под apache, и весь мой код, включая class точки входа из старой банки, попал в WAR-файл для легкого использования в веб-сервере.

Тем не менее, я все еще хочу иметь возможность запускать его из командной строки, и код не изменился и все там, я просто не могу понять, как его запустить.

Вот что я пробовал …

Я предполагал, что ВОЙНА была похожа на банку, поэтому

 java -jar mywar.war params 

Это не показало, что в манифесте не было основного classа.

Я вручную добавил манифест на войну и снова попытался с таким же эффектом.

Я заметил, что в моей войне у меня была папка с именем META-INF, содержащая manifest.mf, поэтому я добавил строку, чтобы объявить мой основной class, как я бы хотел нормальный манифест …

 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, не то, что я думаю, что это должно иметь значение.

Вы можете делать то, что делает Хадсон (проект непрерывной интеграции). вы загружаете войну, которую можно развернуть в tomcat или выполнить с помощью

 java -jar hudson.war 

(Поскольку у него встроенный двигатель Jetty, запуск его из командной строки приводит к запуску сервера.) В любом случае, глядя на манифест hudson, я понимаю, что они помещают основной class в корневой каталог для архива. В вашем случае ваш военный макет должен выглядеть так:

под root:

  • MyPackage / MyEntryPointClass.class
  • WEB-INF / Lib
  • WEB-INF / classы
  • META-INF / MANIFEST.MF

в то время как манифест должен включать следующую строку:

 Main-Class: mypackage.MyEntryPointClass 

обратите внимание, что mypackage / MyEntryPointClass.class доступен только из командной строки, а classы под WEB-INF / classами доступны только с сервера приложений.

НТН

Как и у Ричарда Детша, но с немного легче следовать (работает с пакетами)

Шаг 1. Отвяжите файл войны.

 jar -xvf MyWar.war 

Шаг 2: перейдите в каталог

 cd WEB-INF 

Шаг 3: Запустите главную страницу со всеми зависимыми

 java -classpath "lib/*:classes/." my.packages.destination.FileToRun 

Война – это webapp. Если вы хотите, чтобы консольное / автономное приложение повторно использовало те же classы, что и webapp, рассмотрите возможность упаковки ваших общих classов в банке, которую вы можете поместить в WEB-INF/lib . Затем используйте эту банку из командной строки. Таким образом, вы получаете как консольное приложение, так и вы можете использовать одни и те же classы в своих сервлетах, не создавая двух разных пакетов. Это, конечно, верно, когда война взорвалась.

Чтобы выполнить SomeClass.main (String [] args) из развернутого файла войны, выполните:

Шаг 1: Напишите class SomeClass.java, который имеет метод основного метода, то есть (public static void main (String [] args) {…})

Шаг 2: Разверните свою войну

Шаг 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: (чтобы узнать, находится ли class SomeOtherClass.class в / usr / tomcat / webapps / projectName / WEB-INF / lib)

run -> cd / usr / tomcat / webapps / projectName / WEB-INF / lib && find. -name ‘* .jar’ | при чтении jarfile; do if jar tf “$ jarfile” | grep SomeOtherClass.class; затем echo “$ jarfile”; Fi; сделанный

Примечание2: напишите на стандарт, чтобы вы могли видеть, работает ли ваш основной файл с помощью операторов печати на консоли. Это называется задней дверью.

Примечание3: Комментарий, высказанный Божидаром Божановым, кажется правильным

Правила размещения classов в архиве – это то, что местоположение объявления пакета файла и расположение файла в архиве должны совпадать. Поскольку ваш class находится в WEB-INF / classах, он считает, что class недействителен для запуска в текущем контексте.

Единственный способ сделать то, что вы просите, – переупаковать войну, чтобы файл .class mypackage каталоге mypackage в mypackage каталоге архива, а не в каталоге WEB-INF / classes. Однако, если вы это сделаете, вы больше не сможете получить доступ к файлу с любого из ваших веб-classов.

Если вы хотите повторно использовать этот class как в войне, так и снаружи из командной строки java, подумайте о создании исполняемого банку, который вы можете запустить из командной строки, а затем помещаете эту банку в каталог WEB-INF / lib в war файле.

В проекте Maven вы можете создать банку автоматически, используя плагин Maven War , установив для archiveClasses значение true . Пример ниже.

  org.apache.maven.plugins maven-war-plugin  true   

Если вы используете Maven, просто следуйте документации maven-war-plugin о том, « Как создать JAR, содержащий classы в моем webapp? »: Добавить true в плагина :

  ... mywebapp 1.0-SNAPSHOT ...    maven-war-plugin 2.6  true     ...  

У вас будет 2 продукта в target/ папке target/ папке:

  • Сам project.war
  • project-classes.jar который содержит все скомпилированные classы в банке

Затем вы сможете выполнить основной class с использованием classического метода: java -cp target/project-classes.jar 'com.mycompany.MainClass' param1 param2

Ну, согласно Википедии , с файлом WAR, classы, которые загружаются в путь к classам, находятся в каталоге «/ WEB-INF / classes» и «/ WEB-INF / lib».

Вы можете попробовать просто поместить копию classов в корневую файловую систему zip-файла (что и есть война / банка). Я не уверен, что это сработает.

Вы всегда можете просто создать два отдельных файла.

Невозможно запустить class java из WAR-файла. Файлы WAR имеют другую структуру для файлов Jar.

Чтобы найти связанные classы java, экспортируйте (предпочтительный способ использования муравья), поскольку Jar поместил его в ваше веб-приложение lib.

Затем вы можете использовать файл jar как обычно для запуска java-программы. Тот же банку также упоминался в веб-приложении (если вы положили эту банку в веб-приложение lib)

Давайте будем гением компьютера.