java項目中相同jar的不同版本誰先引入誰先加載
第一種解決辦法:
進行版本之間的整合
第二種解決辦法:
目前只在java項目中成功,J2EE項目中沒成功,所以本次J2EE項目根據java文件所要引入的高版本的jar,直接通過將import的類重新根據class文件編寫
報錯如下
Exception in thread "main" java.lang.SecurityException: class "org.xxx.xxx"'s signer information does not match signer information of other classes in the same package at java.lang.ClassLoader.checkCerts(ClassLoader.java:943) at java.lang.ClassLoader.preDefineClass(ClassLoader.java:657) at java.lang.ClassLoader.defineClass(ClassLoader.java:785) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:449) at java.net.URLClassLoader.access$100(URLClassLoader.java:71) at java.net.URLClassLoader$1.run(URLClassLoader.java:361) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:423) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:356) at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:791) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:449) at java.net.URLClassLoader.access$100(URLClassLoader.java:71) at java.net.URLClassLoader$1.run(URLClassLoader.java:361) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:423) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:356) at cn.csg.soa.isc.interceptor.Sm3Utils.hash(Sm3Utils.java:52) at cn.csg.soa.isc.interceptor.Sm3Utils.encrypt(Sm3Utils.java:36) at cn.csg.soa.isc.interceptor.Sm3Utils.main(Sm3Utils.java:105)
很明顯是有相同的package,而項目在引入包名下的類時出錯(類加載時由於有相同的包路徑,jvm根據加載順序后遇到的相同包路徑下的文件不進行加載,所以當項目需要引入后面這個jar包內容時會出錯)
兩個沖突的jar我們稱為jarA和jarB
解決辦法:將需要引入的jarA包引入項目內,並且在項目名如(test)下創建文件MANIFEST.MF,內容如下,然后進行打包成jarC
測試辦法:將兩個有沖突的jar包和新打好的jarC包引入項目中,(如果只引入新打好的jarC包會出錯,至少需要引入新打好的jarC和之前引入的jarA),三個引入測試是否還會出錯
Manifest-Version: 1.0 Class-Path: ../lib/xxx.jar

第三種解決辦法:
引入一個版本的jar包,另一個jar包如果不能進行整合,可以將需要引入的類編寫進入項目來替代需要引入的包
第四種解決辦法:
自定義類加載類,根據jar包所在的位置加載進入,但是不能將jar放在像WEB-INF/lib這個下面,不然會造成沖突
1 package com.qf.jf; 2 import java.lang.reflect.Method; 3 import java.net.MalformedURLException; 4 import java.net.URL; 5 import java.net.URLClassLoader; 6 public class CustomClassLoader extends ClassLoader{ 7 8 @Override 9 public Class<?> loadClass(String name) throws ClassNotFoundException { 10 return super.loadClass(name); 11 } 12 13 public void test() throws Exception { 14 URLClassLoader clsLoader=null; 15 try { 16 clsLoader = URLClassLoader.newInstance(new URL[] {new URL("file:/C:/XXX/X.1.57.jar")}); 17 } catch (MalformedURLException e) { 18 // TODO Auto-generated catch block 19 e.printStackTrace(); 20 } 21 Class byteUtils=null; 22 Class sm3Digest=null; 23 try { 24 25 byteUtils = clsLoader.loadClass("包名+類名");//比如:org.qf.Test 26 sm3Digest = clsLoader.loadClass("xxx.xx"); 27 } catch (ClassNotFoundException e) { 28 e.printStackTrace(); 29 } 30 //獲取類實例化對象,以便在之后的使用中運用同一個實例 31 Object clazz=sm3Digest.newInstance(); 32 33 Method sm3Method=sm3Digest.getMethod("update", byte[].class,int.class,int.class); 34 sm3Method.invoke(clazz,srcData,0, srcData.length);//此處是一個void方法,如有返回值接收就行38 51 } 52 58 59 public static void main(String[] args)throws Exception { 60 new CustomClassLoader().test(); 61 } 62 63 }
