私は埋め込まれたjettyjavaアプリケーションを持っています。これはそれ自体を起動し、前述のルートでリクエストを処理します。テスト中は問題なく動作しています。このJavaアプリケーションをwarファイルを介してデプロイしたいので、問題が発生します。
実行中java -jar server--1.0-SNAPSHOT.war
:次のようにエラーが発生しますError: Could not find or load main class com.server.core.App
これは、最初の問題が修正された後に発生します。これは、すべての依存関係をwarファイルに含める方法です。
これが私のpom.xml
https://gist.github.com/shadow-fox/24ec2c7d40f4b0e6aae5です
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.server</groupId>
<artifactId>server</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty-version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${jetty-version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>${jetty-version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-jetty-http</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j-version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jdk-version>1.8</jdk-version>
<jetty-version>9.3.3.v20150827</jetty-version>
<jersey-version>2.21</jersey-version>
<junit-version>4.12</junit-version>
<jackson-version>2.6.1</jackson-version>
<log4j-version>2.3</log4j-version>
<mvn-compiler>3.3</mvn-compiler>
<mvn-war>2.6</mvn-war>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${mvn-compiler}</version>
<configuration>
<source>${jdk-version}</source>
<target>${jdk-version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${mvn-war}</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.server.core.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
私が台無しにしたかもしれないところ:classpathPrefixはここで何を設定するべきかわからない。私のクラスはデフォルトでターゲットディレクトリに移動します(IDEA Intellijを使用)。mainClassは同じパスに存在します。
App.java
package com.server.core;
import com.server.core.filters.RequestFilter;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.glassfish.jersey.servlet.ServletContainer;
import java.util.EnumSet;
import javax.servlet.DispatcherType;
public class App {
private static final Logger logger = LogManager.getLogger(App.class);
public static void main(String[] args) throws Exception {
Server server = new Server();
ServerConnector connector = new ServerConnector(server);
connector.setPort(8080);
server.addConnector(connector);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
context.addFilter(RequestFilter.class, "/*", EnumSet.of(DispatcherType.INCLUDE,
DispatcherType.REQUEST, DispatcherType.ASYNC, DispatcherType.ERROR,
DispatcherType.FORWARD));
server.setHandler(context);
ServletHolder servletHolder = new ServletHolder(ServletContainer.class);
servletHolder.setInitOrder(0);
servletHolder.setInitParameter("jersey.config.server.provider.packages", "com/server/core/endpoints");
context.addServlet(servletHolder, "/*");
try {
server.start();
logger.debug("Server started");
logger.debug(server);
server.join();
} catch (Throwable t) {
logger.error(System.err);
} finally {
server.destroy();
}
}
}
これに似た質問がたくさんありますが、このユースケースでは見つかりませんでした。
Jettyを使用した自己実行WARは可能ですが、さまざまなMavenプラグインが自己実行WARの作業を元に戻す傾向があるため、セットアップには少し注意が必要です。
Jettyプロジェクトは、そのようなサンプルプロジェクトを維持しています。
https://github.com/jetty-project/embedded-jetty-live-war
重要なのは、その組み立て方法です。
プロジェクトには4つの主要な部分があります。
/thewebapp/
-これは、ネイティブ形式で存在するWARファイルであるwebappであり、通常のMaven Warと、(まだ)自己実行されない単なるWARファイルである生成されたアーティファクトが含まれています。/theserver/
-これは、jetty.livewar.ServerMain.main(String args[])
JettyサーバーとそのWebAppを初期化するためにカスタマイズするEmbedded JettyServerです。このプロジェクトは、JDBCサーバーライブラリ、JNDI、ロギングなどをカスタマイズする場所でもあります。このプロジェクトは、サーバーの実行に必要なすべての依存関係を備えたuber-jarを生成します。META-INF/services/
ファイルをマージするために、maven-shade-pluginには特別な注意が払われています。/server-bootstrap/
-これにはLiveWarClassLoader
、ライブWARのコンテンツからを設定し、jetty.livewar.ServerMain.main(String args[])
この新しいClassLoaderから実行する2つの小さなクラスが含まれています。このプロジェクトには、META-INF/MANIFEST.MF
ライブWARが必要/使用するライブも含まれています/livewar-assembly/
-これは、上記の3つのプロジェクトをLive / ExecutableWARファイルに結合するプロジェクトです。上記の3つのプロジェクトからのアーティファクトは、maven-assembly-pluginによって解凍され、最も機能的(かつ安全)な場所に配置されます。たとえば、からのサーバークラス/theserver/
は/WEB-INF/jetty-server/
、WARファイルにアクセスするWebクライアントからアクセスできないようにするために配置されます。注:このセットアップを使用すると、これらのファイルを静的コンテンツとしてWebクライアントからダウンロードできるため、新しくアセンブルされたWARファイルには3つのファイルが存在することに注意してください。
/jetty/bootstrap/JettyBootstrap.class
/jetty/bootstrap/LiveWarClassLoader.class
/META-INF/MANIFEST.MF
サンプルプロジェクトは、これらのブートストラップファイルに存在する情報が、サーバーまたはその操作に関する個人情報や機密情報を明らかにしないように設定されています。WebappをLive / ExecutableWARファイルとして開始できるということだけです。
4つのモジュールで1つの実行可能アーティファクトが生成されるのは奇妙に思えるかもしれませんが、この環境をセットアップするために3つのことを扱っていることを理解する必要があります。
/thewebapp/
/theserver/
Main-Class
これです- 2以上のバインド一緒にインテリジェントには(そう、自分のためにセキュリティ上の問題を作成しないために)ことを実行可能/server-bootstrap/
最後のモジュールは/livewar-assembly/
、3つの部分を1つの統合された全体に結び付けるだけです。
私maven-shade-plugin
はそれをすべて使いたくなるかもしれないことを知っていますが、あなたは以下の要件のすべてを達成することはできません(あなたはそれらのいくつかを達成し、次に他のものを修正しようとしますが、最終的に他のものを壊し、ワックアモールの無限のゲーム)..。
META-INF/services
インテリジェントにマージします。META-INF/MANIFEST.MF
ブートストラップ用のカスタムを使用する(META-INF/MANIFEST.MF
すべてのサーバー依存関係からファイルのマージされたコピーを取得することなく)この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加