java使用java -jar执行jar文件(自定义classloader)

本文介绍了使用`java -jar`执行包含依赖的jar文件的多种方式,包括直接执行、加载额外jar、使用Bootstrap及Extension Classloader,并提供了自定义Classloader的执行示例。在某些场景下,需要指定额外的jar路径或使用`-cp`选项。此外,还分享了一个测试案例,演示了如何解决因依赖缺失导致的运行问题。
摘要由CSDN通过智能技术生成

现在比较流行使用java -jar xx.jar命令来执行可执行的jar包,在这里记录一下java -jar 运行jar包的常用方法。

jar里面包含所有依赖包的

一般直接使用java -jar来执行命令就行了,我们会设置内存等常规参数,这种情况适合jar里面包含所有的依赖的情况。

nohup java -Dfile.encoding="utf8"  -Xms1024m -Xmx1024m K  -jar $prjName.jar &
jar包里面包含MANIFEST.MF文件,并且制定了Main-Class属性指定了启动类。
Manifest-Version: 1.0
Class-Path: 
Created-By: 1.4.2 (Sun Microsystems Inc.)
Class-Path: lib/xx.jar  lib/xxa.jar lib/xxb.jar  所有依赖的jar包都在这里配置,这个实现的原理就行使用AppClassloader来实现加载的。
Main-Class: com.imobpay.base.start.Start

需要加载额外jar的情况

有时候我们运行的jar包还需要依赖外部的jar包,也就是没有把依赖包放到执行的jar包里面的时候,就需要指定加载额外的jar包了。

使用Bootstrap Classloader来加载这些类

这个没测试,拷贝的别人的。

-Xbootclasspath:完全取代系统Java classpath.最好不用。
-Xbootclasspath/a: 在系统class加载后加载。一般用这个。
-Xbootclasspath/p: 在系统class加载前加载,注意使用,和系统类冲突就不好了.
win32 java -Xbootclasspath/a: some.jar;some2.jar; -jar test.jar
unix    java -Xbootclasspath/a: some.jar:some2.jar: -jar test.jar
win32系统每个jar用分号隔开,unix系统下用冒号隔开
使用Extension Classloader来加载

java中系统属性java.ext.dirs指定的目录由ExtClassLoader加载器加载
如果您的程序没有指定该系统属性(-Djava.ext.dirs=sss/lib), 那么该加载器默认加载$JAVA_HOME/lib/ext目录下的所有jar文件
但如果你手动指定系统属性且忘了把$JAVA_HOME/lib/ext路径给加上, 那么ExtClassLoader不会去加载$JAVA_HOME/lib/ext下面的jar文件, 这意味着你将失去一些功能, 例如java自带的加解密算法实现,所以最好的同时指定两个目录。

执行代码
这是在Linux上执行的,我把要执行的jar包放在lib的同级目录下,使用-Djava.ext.dirs可以同时指定多个目录,使用:分开。

[paydubbo@qtbj-dmz-102 lib]$ java -Djava.ext.dirs=/home/paydubbo/jdk1.8.0_162/jre/lib/ext/:lib/ -jar xxx.jar 

使用java -cp来执行

这个就是把所有的jar包放在同一个目录,然后使用-cp进行指定,后面接需要执行的类的全路径。(cp是classpath的缩写???)

java -cp  lib/*   com.imobpay.base.Start

使用自定义的Classloader进行加载

这个实现的方式比较多,照搬我们现在的模式。
下面是测试类,把这个类打成一个jar包,执行运行会包Gson找不到了。我传入加载包的的路劲之后就可以运行了,
执行命令
这里我通过jar包后面传参数的形式指定需要加载的jar文件路劲,依赖包和要运行的jar包必须放在同一个目录下面(这是因为我使用了jar包相对路劲)。

  java -jar .\xx.jar C:\Users\Administrator\Desktop\lib

链接:https://pan.baidu.com/s/1bgP2VUIfFEx1I833PCO9dg
提取码:l2lu

package com.madman.base;

import java.io.File;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Base64;
import java.util.Base64.Decoder;

import com.google.gson.Gson;

import sun.misc.Launcher;

/**
 * 类加载器分为:引导加载器-扩展加载器-系统加载器-用户自定义加载器 一般情况下:加载器的原则是:先交于上层加载器加载,如果加载失败,在由自己加载。
 * 因为官方对于类加载器进行了:双亲委派模式进行修饰, 可以保证类加载,尽量不会出现不同加载器加载同一个类的情况出现 具体情况请查询类加载器的描述 <br/>
 * 
 * @ClassName: ClassLoaderUtil<br/>
 * @Description: 类加载器的工具类,(主要用于把class类加载到jvm中)<br/>
 * @version 1.0<br/>
 * @since JDK 1.6<br/>
 * @since PlatForm 1.0<br/>
 * 
 *        Copyright: Copyright (c) 2014 Company:www.imobpay.com<br/>
 */
@SuppressWarnings("restriction")
public class ClassLoaderUtil {

	/** 参数 */
	private static Method addURL;
	/**
	 * 静态块 <br/>
	 * 
	 * @Title: getSystemClassLoader<br/>
	 * @Description: 静态块,用来得到URLClassLoader加载类中的addURL方法<br/>
	 * @Date May 4, 2014 29:19:03 AM<br/>
	 * @modifyDate May 4, 2014 29:19:03 AM<br/>
	 */
	static {
		try {
			addURL = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] { URL.class });
		} catch (Exception e) {
			e.printStackTrace();
		}
		addURL.setAccessible(true);
	}

	/** 系统参数 */
	private static URLClassLoader system = (URLClassLoader) getSystemClassLoader();
	/** 系统参数 */
	private static URLClassLoader ext = (URLClassLoader) getExtClassLoader();

	/**
	 * 获取系统的类加载器<br/>
	 * 
	 * @Title: getSystemClassLoader<br/>
	 * @Description: 获取系统的类加载器<br/>
	 * @Date May 4, 2014 29:19:03 AM<br/>
	 * @modifyDate May 4, 2014 29:19:03 AM<br/>
	 * @return ClassLoader 类加载器对象 java.lang.ClassLoader<br/>
	 */
	public static ClassLoader getSystemClassLoader() {
		return ClassLoader.getSystemClassLoader();
	}

	/**
	 * 获取jdk中ext目录中的加载器,扩展类加载器<br/>
	 *
	 * @Title: getExtClassLoader<br/>
	 * @Description: 获取jdk中ext目录中的加载器,扩展类加载器<br/>
	 * &#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值