Как запустить класс в WAR из командной строки? - PullRequest
60 голосов
/ 04 декабря 2009

У меня есть класс Java, в котором есть main, и я использовал его для запуска в качестве отдельного приложения из командной строки, например,

java -jar myjar.jar params

Мне нужно было переупаковать код для запуска под apache, и весь мой код, включая класс точки входа из старого jar-файла, оказался в файле 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)

Я немного погуглил, но не могу найти ничего, что отвечало бы на мой вопрос, и я прочитал здесь пару других вопросов, которые немного отличаются, поэтому я подумал, что опубликую.

Java 1.5, не то чтобы я думаю, что это должно иметь какое-то значение.

Ответы [ 9 ]

32 голосов
/ 27 сентября 2010

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

java -jar hudson.war

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

под корнем:

  • mypackage / MyEntryPointClass.class
  • WEB-INF / lib
  • WEB-INF / классы
  • META-INF / MANIFEST.MF

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

Main-Class: mypackage.MyEntryPointClass

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

НТН

26 голосов
/ 21 октября 2015

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

Шаг 1: Распакуйте файл War.

jar -xvf MyWar.war

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

cd WEB-INF

Шаг 3: Запустите свой main со всеми зависимостями

java -classpath "lib/*:classes/." my.packages.destination.FileToRun
10 голосов
/ 04 декабря 2009

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

8 голосов
/ 05 апреля 2012

Чтобы выполнить 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 && находить . имя * .jar | пока читаешь jarfile; делать, если jar tf "$ jarfile" | grep SomeOtherClass.class; затем выведите «$ jarfile»; Fi; сделано

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

6 голосов
/ 04 декабря 2009

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

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

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

4 голосов
/ 20 апреля 2011

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

<plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-war-plugin</artifactId>
       <configuration>
        <archiveClasses>true</archiveClasses>
       </configuration>
</plugin>
2 голосов
/ 16 февраля 2016

Если вы используете Maven, просто следуйте документации maven-war-plugin о " Как создать JAR, содержащий классы в моем веб-приложении? ": добавьте <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>

В папке target/ будет 2 продукта:

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

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

0 голосов
/ 08 июня 2015

Невозможно запустить класс Java из файла WAR. WAR-файлы имеют структуру, отличную от файлов Jar.

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

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

0 голосов
/ 04 декабря 2009

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

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

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

...