Исполняемый военный файл, который запускает причал без знатока

Я пытаюсь сделать "исполняемый" военный файл (java -jar myWarFile.war) это запустит Гагатовый веб-сервер, который размещает веб-приложение, содержавшееся в ВОЕННОМ файле, который я выполнил.

Я нашел страницу, которая описала, как сделать то, что я ищу:

Однако следование тому совету наряду с тем, как я думаю, что я, как предполагается, делаю исполняемую банку (война), не работает.

У меня есть задача Ant, создающая ВОЕННЫЙ файл с декларацией, которая похожа:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.1
Created-By: 1.5.0_18-b02 (Sun Microsystems Inc.)
Main-Class: Start

Содержание ВОЕННОГО файла похоже:

> Start.class
> jsp
>   build.jsp 
> META-INF  
>   MANIFEST.MF
> WEB-INF
>   lib
>     jetty-6.1.22.jar
>     jetty-util.6.1.22.jar

Когда я пытаюсь выполнить ВОЕННЫЙ файл, ошибка:

Exception in thread "main" java.lang.NoClassDefFoundError: org/mortbay/jetty/Handler
Caused by: java.lang.ClassNotFoundException: org.mortbay.jetty.Handler
        at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
Could not find the main class: Start. Program will exit.

Здесь, кажется, существует две ошибки: тот, где это кажется файлами JAR, не может быть найден, и тот где Start класс не может быть найден.

Для фиксации первого я поместил Причал файлы JAR в основу ВОЕННОГО файла и попробовал еще раз - та же ошибка. Я также пытался добавить WEB-INF/lib/ к Class-Path атрибут декларации. Это не работало также.

У кого-либо есть понимание относительно того, что я делаю право/несправедливость и как я могу разбудить этот исполняемый ВОЕННЫЙ файл и выполнение?

52
задан Christian Conti-Vock 26 February 2013 в 07:35
поделиться

5 ответов

Ссылка ссылка, которая у вас есть в вашем вопросе, предоставляет большую часть того, что вам нужно. Тем не менее, есть несколько вещей, которые необходимо сделать в дополнение к этому.

Любые файлы классов, которые Jetty необходимо запустить, должны быть расположены в корневом каталоге военного файла при его упаковке. Мы можем использовать Ant, чтобы сделать это за нас, прежде чем мы файл. Файлу манифеста войны также потребуется атрибут Main-Class для выполнения сервера.

Вот шаг за шагом:

Создайте класс сервера Jetty:

Он адаптирован по предоставленной вами ссылке.

package com.mycompany.myapp;

import java.io.File;
import java.net.URL;
import java.security.ProtectionDomain;

import org.mortbay.jetty.Server;
import org.mortbay.jetty.webapp.WebAppContext;

public final class EmbeddedJettyServer
{
    public static void main(String[] args) throws Exception
    {
        int port = Integer.parseInt(System.getProperty("port", "8080"));
        Server server = new Server(port);

        ProtectionDomain domain = EmbeddedJettyServer.class.getProtectionDomain();
        URL location = domain.getCodeSource().getLocation();

        WebAppContext webapp = new WebAppContext();
        webapp.setContextPath("/");
        webapp.setDescriptor(location.toExternalForm() + "/WEB-INF/web.xml");
        webapp.setServer(server);
        webapp.setWar(location.toExternalForm());

        // (Optional) Set the directory the war will extract to.
        // If not set, java.io.tmpdir will be used, which can cause problems
        // if the temp directory gets cleaned periodically.
        // Your build scripts should remove this directory between deployments
        webapp.setTempDirectory(new File("/path/to/webapp-directory"));

        server.setHandler(webapp);
        server.start();
        server.join();
    }
}

Чтобы узнать, что вы можете настроить здесь, взгляните на документацию по API Jetty.

Постройте войну с муравьем:

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

<target name="war" description="--> Creates self-executing war">
  <property name="staging.dir" location="${basedir}/staging"/>
  <property name="webapp.dir" location="${basedir}/src/webapp"/>

  <mkdir dir="${staging.dir}"/>

  <!-- assumes you have all of your war content (excluding classes and libraries) already structured in a directory called src/webapp -->
  <!-- e.g. -->
  <!-- src/webapp/index.html -->
  <!-- src/webapp/WEB-INF/web.xml -->
  <!-- src/webapp/WEB-INF/classes/my.properties -->
  <!-- etc ... -->
  <copy todir="${staging.dir}">
    <fileset dir="${webapp.dir}" includes="**/*"/>
  </copy>

  <unjar dest="${staging.dir}">
    <!-- you'll have to locate these jars or appropriate versions; note that these include JSP support -->
    <!-- you might find some of them in the downloaded Jetty .tgz -->
    <fileset dir="path/to/jetty/jars">
      <include name="ant-1.6.5.jar"/>
      <include name="core-3.1.1.jar"/>
      <include name="jetty-6.1.24.jar"/>
      <include name="jsp-2.1-glassfish-2.1.v20091210.jar"/><!-- your JSP implementation may vary -->
      <include name="jsp-api-2.1-glassfish-2.1.v20091210.jar"/><!-- your JSP implementation may vary -->
      <include name="servlet-api-2.5-20081211.jar"/><!-- your Servlet API implementation may vary -->
    </fileset>
    <patternset><!-- to exclude some of the stuff we don't really need -->
      <exclude name="META-INF/**/*"/>
      <exclude name="images/**/*"/>
      <exclude name=".options"/>
      <exclude name="about.html"/>
      <exclude name="jdtCompilerAdapter.jar"/>
      <exclude name="plugin*"/>
    </patternset>
  </unjar>

  <!-- copy in the class file built from the above EmbeddedJettyServer.java -->
  <copy todir="${staging.dir}">
    <fileset dir="path/to/classes/dir" includes="com/mycompany/myapp/EmbeddedJettyServer.class"/>
  </copy>

  <war destfile="myapp.war" webxml="${webapp.dir}/WEB-INF/web.xml">
    <fileset dir="${staging.dir}" includes="**/*"/>
    <classes dir="path/to/classes/dir"/><!-- your application classes -->
    <lib dir="path/to/lib/dir"/><!-- application dependency jars -->
    <manifest>
      <!-- add the Main-Class attribute that will execute our server class -->
      <attribute name="Main-Class" value="com.mycompany.myapp.EmbeddedJettyServer"/>
    </manifest>
  </war>

  <delete dir="${staging.dir}"/>
</target>

Выполните войну:

Если все настроено правильно выше, вы должны быть в состоянии:

java -jar myapp.war

// or if you want to configure the port (since we are using the System property in the code)

java -Dport=8443 -jar myapp.war
50
ответ дан 7 November 2019 в 09:10
поделиться

Hudson решает именно эту проблему с помощью контейнера сервлетов Winstone, который поддерживает этот вариант использования напрямую. http://winstone.sourceforge.net/#embedding

Возможно, это подойдет вам?

7
ответ дан 7 November 2019 в 09:10
поделиться

Я делал то же самое раньше, но запускаете ли вы приложение как «java -jar xxx.war»? У вас всего 2 банки, и я думаю, этого будет недостаточно. Также попробуйте использовать Jetty 7.0.0M1 (последняя версия). Когда я добавил причал-сервер и причал-webapp в качестве двух зависимостей (они взяты из org.eclipse.jetty), я получил следующую банку в каталоге lib. К вашему сведению, org.mortbay.jetty.Handler находился на причальном сервере * .jar.

  • причал-продолжение-7.0.0.M1.jar
  • причал-http-7.0.0.M1.jar
  • причал-io-7.0.0.M1.jar
  • причал-безопасность-7.0 .0.M1.jar
  • причал-сервер-7.0.0.M1.jar
  • причал-сервлет-7.0.0.M1.jar
  • причал-утилит-7.0.0.M1.jar
  • jetty-webapp-7.0.0.M1.jar
  • jetty-xml-7.0.0.M1.jar
0
ответ дан 7 November 2019 в 09:10
поделиться
  • Помещение .jars в корень файла .war ничего не дает
  • Помещение .jars внутрь WEB-INF / lib не работает помогите JVM найти файлы Jetty, чтобы даже начать запуск вашего .war. «Слишком поздно» их туда класть.
  • Помещение .jars в манифест Class-Path работает только для внешних файлов .jar, а не для файлов, содержащихся в .jar

Итак, что делать?

  • Используйте сценарий сборки, чтобы просто объединить все файлы .jar вам нужно в файл .war. Это требует небольшой дополнительной работы. Это также немного уродливо, поскольку скомпилированный код является частью обслуживаемых файлов в .war
  • . Добавьте зависимые .jars в путь к классам JVM с помощью "java -cp jetty.jar: ... ..." Работает, хотя это своего рода поражает цель одного автономного .war
0
ответ дан 7 November 2019 в 09:10
поделиться

Это мой пример извлечения ANT. Идея состоит в том, чтобы распаковать зависимости Jetty, а затем включить их локально, как обычный файл JAR:

<!-- Hack: Java doesn't support jars within jars/wars -->
<unjar src="${lib.dir}/container/jetty.jar" dest="${build.dir}/unjar"/>
<unjar src="${lib.dir}/container/jetty-util.jar" dest="${build.dir}/unjar"/>
<unjar src="${lib.dir}/container/servlet-api.jar" dest="${build.dir}/unjar"/>
<unjar src="${lib.dir}/container/jsp-api.jar" dest="${build.dir}/unjar"/>

<!-- Build war file as normal, just including the compiled and unjar'ed files -->
<war destfile="${war.file}" webxml="${config.dir}/web.xml">
    <fileset dir="${build.dir}/classes"/>
    <fileset dir="${build.dir}/unjar"/>
    <fileset dir="${resources.dir}" excludes="*.swp"/>
    <lib dir="${lib.dir}/runtime"/>
    <manifest>
        <attribute name="Main-Class" value="Start"/>
    </manifest>
</war>

Примечание:

Директория WEB-INF / lib предназначена для зависимостей веб-приложений. В этом случае мы упаковываем WAR-файл, чтобы он работал как обычный JAR-файл Jetty при запуске

1
ответ дан 7 November 2019 в 09:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: