Подтвердить что ты не робот

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

4b9b3361

Ответ 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)