有没有办法使用onejar-maven-plugin将任意类路径条目添加到JAR文件清单?
我找到了配置maven-jar-plugin来实现这一目标的方法,但似乎没有针对onejar-maven-plugin的选项.
这不是为了找到其他类(否则为什么要使用onejar插件,对吧?),而是找到一个必须在JAR外部的配置文件.
对此有直接的解决方案或解决方法吗?
我们目前正在研究在我们的应用程序中使用OneJar(由于多种原因),但我们的应用程序使用了许多自定义URLClassloader来加载应用程序扩展.
当捆绑为"OneJar"Jar时,我们会遇到ClassNotFound异常.有问题的类存在于捆绑的Jar中,我们只是依靠类加载器机制来解析父/子关系.
那是.我们有一个共同interface的存储在捆绑的Jar中(应该在父类的类加载器上下文中).扩展实现了这一点interface(允许我们调用扩展)并依赖子类加载器使用父类加载器的资源查找功能的能力.
是否有任何人对此有任何经验或对我们如何解决它有任何启示.
我很想在其它类似机制(捆绑我们的库JAR的到一个JAR资源,不需要使用一切,罐其unjar成一个单一的文件)
我希望结合/嵌入Tomcat 和我的网络应用程序作为onejar aka胖罐但我不确定它是否可能.使用Maven Shade插件和Winstone可以使用Jetty但是我尝试了类似于Tomcat 7的东西并且无法正确加载它.目标是能够做到:java -jar mywebapp.jar.
问题是Tomcat想要从文件系统而不是从类路径加载东西.也就是说,您可以嵌入Tomcat,但它会期望您的WAR文件可用作文件.
我尝试了以前SO帖子中的许多技术来嵌入Tomcat 6和7.虽然我可以嵌入它并启动它无法访问我的应用程序.
我想一个选项是有开机的JAR解压缩本身,以便AppBase与DocBase在文件系统上的文件.我还没试过,但是会的.
这里有一个重复的问题,我终于找到了:嵌入Tomcat的自包含war文件?(请以复制方式投票结束)
故意破坏下面的代码以识别NullPointerException的来源,这应该是非常简单的,但结果却让我疯狂:
Properties properties = new Properties();
Thread currentThread = Thread.currentThread();
ClassLoader contextClassLoader = currentThread.getContextClassLoader();
InputStream propertiesStream = contextClassLoader.getResourceAsStream("resource.properties");
if (propertiesStream != null) {
properties.load(propertiesStream);
// TODO close the stream
} else {
// Properties file not found!
}
Run Code Online (Sandbox Code Playgroud)
我收到"未找到属性文件!" 错误,即contextClassLoader.getResourceAsStream("resource.properties"); 返回null.
这是一个基于CXF的客户端和我验证了"resource.properties"文件是在当前目录中的客户端的jar驻留(和运行).
我还通过包含以下诊断代码验证了绝对路径:
File file = new File("resource.properties");
System.out.println(file.getAbsolutePath());
Run Code Online (Sandbox Code Playgroud)
绝对路径指向客户端jar的位置.
我也尝试使用以下方法找出类加载器的上下文:
System.out.println(Thread.currentThread().getContextClassLoader());
Run Code Online (Sandbox Code Playgroud)
但相反,这里演示了一些目录结构,我得到的是:
com.simontuffs.onejar.JarClassLoader@1decdec
为什么ClassLoader.getResourceAsStream()会返回null?
我错过了什么?
编辑:问题改写:
我创建了一个新的最小例子来说明我的问题.这里首先是一个简单类App.java的源代码:
package testlog4j.testlog4j;
import java.io.*;
import java.net.*;
import org.apache.log4j.*;
import org.apache.log4j.xml.*;
public class App
{
static Logger logger = Logger.getLogger(App.class);
URL url = getClass().getClassLoader().getResource("log4j.xml");
public static void main( String[] args )
{
App app = new App();
DOMConfigurator.configure(app.url);
System.out.println( "Hello World!" );
System.out.println("Resource(.): " + App.class.getResource("."));
System.out.println("Resource(): " + App.class.getResource(""));
System.out.println("URL :" + app.url.toString());
logger.info("INFO");
}
}
Run Code Online (Sandbox Code Playgroud)
其次,这是项目的pom.xml文件
<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>testlog4j</groupId>
<artifactId>testlog4j</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>testlog4j</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration> …Run Code Online (Sandbox Code Playgroud) 我使用One-Jar工具将我的应用程序打包在一个jar中:
http://one-jar.sourceforge.net/
它有效,但我在依赖模块中实现的服务存在问题,该模块在一个单独的jar中实现.
该模块使用标准的Java ServiceLoader机制来提供其服务,即jar有一个文件META-INF/services/package.name.ServiceProviderClass,它指定要实例化的服务具体类.
但是当这个jar嵌入在由One-Jar创建的应用程序"fat-jar"中时,服务加载器机制不会发现它.
知道如何让它工作吗?
干杯,保罗
在我的pom.xml中有这个依赖项部分:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>2.7.1</version>
<type>jar</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>2.7.1</version>
<type>jar</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.0.7.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.26</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.2.6.Final</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-api</artifactId>
<version>2.7.1</version>
<exclusions>
<exclusion>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-javamail_1.4_spec</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>2.7.1</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
Run Code Online (Sandbox Code Playgroud)
我希望从构建中排除geronimo-javamail_1.4_spec包,实际上,当我运行时mvn dependency:tree,它不再列在那里.
但是,在运行生成的jar时,JarClassLoader仍然抱怨jronax/mail类被geronimo隐藏了......
果然,当我通过7-zip检查jar时,我看到geronimo-javamail_1.4_spec-1.7.1.jar仍然存在(作为org.apache.cxf的一部分:cxf-api:jar:2.7. …
我有以下代码:
fun main(args: Array<String>) {
val urlForCSR: URL = ClassLoader.getSystemClassLoader().getResource("merchant.id")
// also tried ClassLoader.getSystemResource("merchant.id")
...
Run Code Online (Sandbox Code Playgroud)
从intelliJ运行时,以下工作正常并找到资源.但是当使用捆绑的jar运行它时会给出一个NullPointerException.
/src/main/resources/merchant.id/src/main/java/Route.kt以下是Maven配置代码段:
...
<!-- Make this jar executable -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>RouteKt</mainClass> <!-- Class generated (for above main func - named Route.kt) -->
</manifest>
</archive>
</configuration>
</plugin>
<!-- Includes the runtime dependencies -->
<plugin>
<groupId>org.dstovall</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.4</version>
<executions>
<execution>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Run Code Online (Sandbox Code Playgroud)
有没有其他的战争来获取上述资源的URL,这可以使用一个jar或其他方式制作一个胖罐.
Jar内容:
jar tf target/Route-1.0-SNAPSHOT.jar
META-INF/
META-INF/MANIFEST.MF
merchant.id
RouteKt$main$1.class …Run Code Online (Sandbox Code Playgroud)