我正在使用Apache CXF JAX-RS在Eclipse中构建项目。当我在Eclipse中运行我的主类时,它工作正常。当我在maven中构建一个具有依赖关系的jar时,它不起作用。这是我的pom.xml(我通过运行“mvn clean compile assembly:single”来构建):
<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.theopentutorials.jaxrs</groupId>
<artifactId>JsonCxfProvider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-extension-providers</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
<version>1.3.3</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2.7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.theopentutorials.jaxrs.calc.CalcRESTStartUp</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
</project>
这是我的主要课程:
public static void main(String[] args) {
JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
sf.setResourceClasses(ResultsXml.class);
sf.setResourceProvider(ResultsXml.class, new SingletonResourceProvider(new ResultsXml()));
sf.setAddress("http://localhost:9999/open/");
Server server = sf.create();
}
其中ResultsXml基本上是一个带注释的pojo类。在Eclipse中运行时,我可以在localhost:9999 / open /上发出请求,然后我得到了我期望的JSON。但是,当我在maven中构建然后使用java -jar myjarfile.jar运行时,我收到以下错误:
线程“main”中的异常 org.apache.cxf.service.factory.ServiceConstructionException 在org.apache.cxf.jaxrs.JAXRSServerFactoryBean.create(JAXRSServerFactoryBean.java:197) 在com.theopentutorials.jaxrs.calc.CalcRESTStartUp.main(CalcRESTStartUp.java:15) 引起:org.apache.cxf.BusException:没有DestinationFactory 找到了名称空间http://cxf.apache.org/transports/http。 at org.apache.cxf.bus.managers.DestinationFactoryManagerImpl.getDestinationFactory(DestinationFactoryManagerImpl.java:130) at org.apache.cxf.endpoint.ServerImpl.initDestination(ServerImpl.java:88) 在org.apache.cxf.endpoint.ServerImpl。(ServerImpl.java:72) 在org.apache.cxf.jaxrs.JAXRSServerFactoryBean.create(JAXRSServerFactoryBean.java:155) ......还有1个
到目前为止我在Google / StackOverflow上找到的所有内容都表明此错误来自缺少的META-INF / cxf / cxf.xml文件 - 这是有道理的,因为我没有其中之一。但是它如何在Eclipse中运行呢?
是不是Eclipse正在从其中一个依赖jar中获取cxf.xml文件,而这个依赖jar碰巧有我需要的配置,但是当使用maven打包时,它会以不同的顺序拾取它们因此不起作用?我试图创建自己的cxf.xml文件,但我不确定哪一个(maven构建日志建议在我的所有依赖项之间,大约有12个文件副本)要使用 - 有没有办法找到Eclipse正在挑选哪一个?
EDIT1
我尝试使用eclipse导出带有解压缩依赖项的可运行jar文件,当eclipse导出的jar我得到一个类似但略有不同的消息:
无法从总线中找到任何已注册的HttpDestinationFactory。 org.apache.cxf.transport.http.HTTPTransportFactory
线程“main”中的异常 org.apache.cxf.service.factory.ServiceConstructionException at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.create(JAXRSServerFactoryBean.java:199) 在com.theopentutorials.jaxrs.calc.CalcRESTStartUp.main(CalcRESTStartUp.java:15) 引起:java.io.IOException:找不到任何已注册的 来自总线的HttpDestinationFactory。 at org.apache.cxf.transport.http.HTTPTransportFactory.getDestination(HTTPTransportFactory.java:295) 在org.apache.cxf.endpoint.ServerImpl.initDestination(ServerImpl.java:93) 在org.apache.cxf.endpoint.ServerImpl。(ServerImpl.java:72) 在org.apache.cxf.jaxrs.JAXRSServerFactoryBean.create(JAXRSServerFactoryBean.java:155)
EDIT2
我尝试使用eclipse导出一个带有'package required libraries into jar'的可运行jar文件 - 到目前为止,这似乎正在运行。是否可以在maven中复制它?
答案 0 :(得分:3)
这个maven-shade-plugin配置对我有用:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<!-- Optional Start -->
<finalName>${artifactId}-${version}</finalName>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>jar-with-dependencies</shadedClassifierName>
<!-- Optional End -->
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.logslie.main</mainClass>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
<resource>META-INF/cxf/cxf-extension-xml.xml</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/cxf/bus-extensions.txt</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
<resource>META-INF/cxf/cxf-extension-http-jetty.xml</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
<resource>META-INF/cxf/cxf-extension-http.xml</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
<resource>META-INF/cxf/cxf-servlet.xml</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
<resource>META-INF/cxf/cxf.xml</resource>
</transformer>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
答案 1 :(得分:2)
对我来说,当我遇到与Spring库完全相同的问题时,我发现它的正确解决方法是使用Maven Shade插件:
http://maven.apache.org/plugins/maven-shade-plugin/
因为几个cxf- * jar中的文件名相同(例如META-INF / cxf / cxf.xml),所以正常的jar-with-dependencies构建将包含第一个,然后忽略所有后续的发现&#39;重复&#39;。 shade插件会将这些文件连接在一起,因此最终会在最后包含一个包含所需条目的大文件。
答案 2 :(得分:1)
我想你使用maven程序集插件创建的zip。当使用jar-with-dependencies时,此插件会将依赖jar中的所有文件合并到一个jar文件中。如果某个文件在各个jar中具有相同的名称和路径,则只保留其中一个重复的文件。在您的情况下,我认为它是来自cxf-rt-transports-http-jetty jar文件的/META-INF/cxf/bus-extensions.txt,它不会出现在生成的程序集zip文件中。 在Eclipse中,没有完成jar文件的合并,因此加载了每个bus-extensions.txt。