Java ClassLoarder 加载 jar 包里面的 class
一、不同启动方式的测试代码
ClassLoader cl = JarClApp. class . getClassLoader ( ) ;
String pkg = JarClApp. class . getPackage ( ) . getName ( ) ;
System. out. printf ( "Find pkg: %s, cl: %s %n" , pkg, cl) ;
String path = pkg. replaceAll ( "\\." , "/" ) ;
URL resource = cl. getResource ( path) ;
assert resource != null;
System. out. printf ( "Find resource %s, protocol: %s %n" , resource, resource. getProtocol ( ) ) ;
Find pkg: com.bheternal.jhome.lang.cl, cl: sun.misc.Launcher$AppClassLoader@18b4aac2
Find resource file:/Users/zain/code/1.my-code/JHome/lang/java-classloader/target/classes/com/bheternal/jhome/lang/cl, protocol: file
Find pkg: com.bheternal.jhome.lang.cl, cl: sun.misc.Launcher$AppClassLoader@5c647e05
Find resource jar:file:/Users/zain/code/1.my-code/JHome/lang/java-classloader/target/java-classloader-1.0-SNAPSHOT.jar! /com/bheternal/jhome/lang/cl, protocol: jar
二、JarURL 解析
private static void handlerJar ( URL resource) throws IOException {
JarURLConnection jarUrl = ( JarURLConnection) resource. openConnection ( ) ;
URL jarFileUrl = jarUrl. getJarFileURL ( ) ;
Attributes attributes = jarUrl. getAttributes ( ) ;
String entryName = jarUrl. getEntryName ( ) ;
JarEntry jarEntry = jarUrl. getJarEntry ( ) ;
JarFile jarFile = jarUrl. getJarFile ( ) ;
System. out. printf ( "jarFileUrl: %s %n" , jarFileUrl) ;
System. out. printf ( "attributes: %s %n" , attributes) ;
System. out. printf ( "entryName: %s %n" , entryName) ;
System. out. printf ( "jarEntry: %s %n" , jarEntry) ;
System. out. printf ( "jarFile: %s %n" , jarFile) ;
}
jarFileUrl: file:/Users/zain/code/1.my-code/JHome/lang/java-classloader/target/java-classloader-1.0-SNAPSHOT.jar
attributes: null
entryName: com/bheternal/jhome/lang/cl
jarEntry: com/bheternal/jhome/lang/cl/
jarFile: sun.net.www.protocol.jar.URLJarFile@135fbaa4
private static void handlerJarFile ( JarFile jarFile) {
jarFile. stream ( ) . forEach ( jarEntry - > {
System. out. printf ( "jarEntry: %s %n" , jarEntry) ;
} ) ;
}
jarEntry: META-INF/
jarEntry: META-INF/MANIFEST.MF
jarEntry: com/
jarEntry: com/bheternal/
jarEntry: com/bheternal/jhome/
jarEntry: com/bheternal/jhome/lang/
jarEntry: com/bheternal/jhome/lang/cl/
jarEntry: com/bheternal/jhome/lang/cl/ClCategoryApp.class
jarEntry: com/bheternal/jhome/lang/cl/candidate/
jarEntry: com/bheternal/jhome/lang/cl/candidate/DemoB.class
jarEntry: com/bheternal/jhome/lang/cl/candidate/DemoC.class
jarEntry: com/bheternal/jhome/lang/cl/candidate/DemoA.class
jarEntry: com/bheternal/jhome/lang/cl/JarClApp.class
jarEntry: META-INF/maven/
jarEntry: META-INF/maven/com.bheternal.jhome/
jarEntry: META-INF/maven/com.bheternal.jhome/java-classloader/
jarEntry: META-INF/maven/com.bheternal.jhome/java-classloader/pom.xml
jarEntry: META-INF/maven/com.bheternal.jhome/java-classloader/pom.properties
三、实例化 Jar 的 Class 文件
private static void handlerJarFile ( JarFile jarFile) throws Exception {
List< JarEntry> jarEntries = new LinkedList < > ( ) ;
jarFile. stream ( )
. filter ( jarEntry - > jarEntry. getName ( ) . startsWith ( path + File. separator + "candidate" ) )
. filter ( jarEntry - > jarEntry. getName ( ) . endsWith ( ".class" ) )
. forEach ( jarEntry - > {
System. out. printf ( "jarEntry: %s %n" , jarEntry) ;
jarEntries. add ( jarEntry) ;
} ) ;
for ( JarEntry jarEntry : jarEntries) {
String classPath = jarEntry. getName ( ) ;
String classPkg = classPath
. replaceAll ( File. separator, "\\." )
. replaceAll ( "\\.class" , "" ) ;
Class< ? > tClass = Class. forName ( classPkg) ;
System. out. printf ( "tClass: %s %n" , tClass) ;
}
}
tClass: class com.bheternal.jhome.lang.cl.candidate.DemoB
tClass: class com.bheternal.jhome.lang.cl.candidate.DemoC
tClass: class com.bheternal.jhome.lang.cl.candidate.DemoA