`
javapolo
  • 浏览: 131571 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

采用类加载器解决jar hell(jar冲突)问题

    博客分类:
  • jvm
 
阅读更多

问题描述:

由于历史原因,系统采用了很早期的poi,而最新的poi和之前版本并不兼容,现在要系统要增加一个新功能,需要引入最新的jar文件,在不影响已有使用的基础上,我们如何处理该问题?

解决方案:

本人的思路是写一个类加载器,动态的加载所需的jar文件到一个单独的命名空间,由于jvm默认的类加载是采用父委托机制的,但在这里,类加载器的实现思路和一些web 容器的类加载机制是一致的(如tomcat jetty等) ,即优先加载自己指定路径下的jar文件,如果加载不到所需的类文件则委托给父加载器,所以我们需重写ClassLoader的loadClass方法,最后上代码,代码很简单,但有一点比较重要,即默认java类所依赖的类是采用和该类相同的类加载器加载的

 

public class ParentLastClassLoader extends ClassLoader{
 
   private String[] jarFiles; //jar文件路径
   
   private Hashtable classes = new Hashtable(); //将定义的类缓存在hashtable里面
 
   public ParentLastClassLoader(ClassLoader parent, String[] paths)
   {
       super(parent);
       this.jarFiles = paths;
   }
 
   @Override
   public Class<?> findClass(String name) throws ClassNotFoundException
   {
       throw new ClassNotFoundException();
   }
 
   @Override
   protected synchronized Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException
   {
       try
       {
           byte classByte[];
           Class result = null;
           //先从缓存中查看是否已经加载该类
           result = (Class) classes.get(className);
           if (result != null) {
               return result;
           }
          //如果没找到该类,则直接从jar文件里面加载
           for(String jarFile: jarFiles){
               try {
                   JarFile jar = new JarFile(jarFile);
                   JarEntry entry = jar.getJarEntry(className.replace(".","/") + ".class");
                   InputStream is = jar.getInputStream(entry);
                   ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
                   int nextValue = is.read();
                   while (-1 != nextValue) {
                       byteStream.write(nextValue);
                       nextValue = is.read();
                   }
                   classByte = byteStream.toByteArray();
                   if(classes.get(className) == null){
                   result = defineClass(className, classByte, 0, classByte.length, null);
                   classes.put(className, result);
                   }
               } catch (Exception e) {
                   continue;
               }
           }
           result = (Class) classes.get(className);
           if (result != null) {
               return result;
           }
           else{
               throw new ClassNotFoundException("Not found "+ className);
           }
       }
       catch( ClassNotFoundException e ){
           return super.loadClass(className, resolve);
       }
   }
}

 

分享到:
评论

相关推荐

    如何在WebSphere中解决jar包冲突.doc

    为了解决这个问题,本文将从 WebSphere 中类加载器入手,讨论几种解决 jar 包冲突问题的办法。 WebSphere 中类加载器的层次结构 在 WebSphere 中,类加载器的层次结构是一个自上而下的分层结构,最上层是系统的...

    weblogic部署项目jar冲突解决

    4. **设置耳聋类加载器(Deaf ClassLoader)**:对于某些特定的JAR包,可以设置为“耳聋”模式,使其不响应父类加载器的请求,从而避免冲突。 5. **使用模块化(OSGi)**:如果应用是基于OSGi的,可以通过模块化...

    如何在was中解决jar包冲突.pdf

    解决 jar 包冲突问题需要深入了解 WAS 中类加载器的工作机制,并根据实际情况选择合适的解决方法。 本文还详细介绍了 WAS 中类加载器的层次结构,包括 JVM Class loader、WebSphere Extensions Class loader、...

    解决网上应用厅部署在was上jar包冲突问题

    Java采用双亲委派模型来处理类加载过程,这对于理解如何解决类路径冲突问题非常重要。 - **WAS红皮书**:官方发布的WAS红皮书提供了详细的类加载说明,包括如何配置类加载顺序等内容。这对于深入理解WAS的工作机制...

    websphere下部署CXF项目jar包冲突问题解决方式

    "websphere下部署CXF项目jar包冲突问题解决方式"这一主题聚焦于如何在IBM Websphere Application Server (WAS)中成功部署包含Apache CXF Web服务的WAR包,解决由于类加载导致的运行异常。 Apache CXF是一个流行的...

    在可执行jar中载入第三方jar的几个解决方法

    自JDK 1.2以来,JVM采用委托模式加载类,先由引导类加载器(Bootstrap ClassLoader)加载核心类,接着是由扩展类加载器(Extension ClassLoader)加载扩展类,最后由应用程序类加载器(AppClassLoader)加载用户类。...

    osgi解决不同版本jar包冲突的demo

    为了解决这个问题,OSGi引入了模块化概念,每个模块(称为bundle)都有自己的类加载器,可以在同一环境中并行运行不同版本的库。 在"myself"工程中,我们创建了两个不同版本的“myself”jar包。每个jar包都包含了...

    动态加载jar包

    同时,使用动态加载可以避免类冲突,因为自定义类加载器可以拥有自己的命名空间。 总结来说,动态加载jar包是Java编程中的一种高级技巧,它使程序具备了高度的灵活性和可扩展性。通过自定义类加载器和反射机制,...

    jar包中类的加载及jar中资源的使用

    1. 使用`Class.forName()`或`ClassLoader.loadClass()`:通过这两个方法可以指定`jar`包中的类路径,让类加载器找到并加载类。例如,`ClassLoader.loadClass("com.example.MyClass", true)`,其中第一个参数是类全名...

    解决jar包冲突的工具类jarjar-1.4.rar

    解决jar包冲突的工具类jarjar-1.4.rar,jar包冲突解决方法,解决jar与jar冲突,jar与aar冲突,不想删除任何一个包,只能修改其中一个jar包包名即可解决,解决方法详细请看这篇文章: ...

    Java 动态加载jar文件示例

    标签“Java 动态加载”不仅涵盖了上述的基础知识,还可能涉及更高级的话题,如类加载器的线程安全、双亲委派模型的打破以及如何处理类加载冲突等。在实际项目中,这些知识对于构建复杂、可扩展的应用程序是必不可少...

    SSH整合jar包,彻底解决集成jar包冲突问题

    5. **合理组织类加载器**:在应用服务器如Tomcat中,可以通过调整类加载策略,比如使用`WEB-INF/classes`优先加载,避免不同模块重复引入的jar包产生冲突。 6. **使用jar包管理工具**:例如,使用FatJar或者One-Jar...

    jar包冲突检测工具

    - **使用类加载器策略**:例如,使用自定义类加载器来控制类的加载顺序,避免冲突。 - **升级或降级依赖**:选择一个兼容的版本,或者对所有依赖进行统一版本管理,例如采用最新稳定版。 总的来说,"jar包冲突检测...

    检查jar包冲突

    - **类加载器策略**:某些应用服务器允许配置类加载器策略,例如优先加载某个`jar`包中的类,以此避免冲突。 3. **依赖管理**: - **统一版本**:尽可能使所有依赖项保持相同的版本,尤其是对有冲突的库。 - **...

    JSONObject所须个包 已解决jar冲突

    4. **使用类加载器策略**:在某些情况下,可以通过自定义类加载器策略来处理冲突。不同的类加载器可以加载不同版本的相同类,从而避免冲突。 5. **模块化系统**:在Java 9及以上版本,你可以利用Jigsaw模块系统来更...

    动态加载jar包的实现

    在Java编程环境中,动态加载jar包是一项重要的技术,...`CSClassLoaderUtil`是这样的类加载器的一个实例,它可能是用Java编写的一个实用工具类,具体实现细节可能包括jar文件的读取、类的加载以及双亲委派模型的遵循。

    jarjar-1.4.jar

    - **类加载器**:在使用jarjar处理后的jar包时,可能需要调整类加载器的策略,确保新的类路径能够正确地加载和解析类。 - **测试与验证**:对处理后的jar包进行充分的测试,确保所有功能都能正常工作,因为类的...

    jar包冲突检测工具.zip

    "jar包冲突检测工具"正是为了解决这个问题而设计的。 这个工具的主要功能是帮助开发者检测出项目中可能存在的jar包冲突。它的工作原理可能是通过遍历指定路径下的所有jar文件,然后对比每个jar中的类文件,找出具有...

    Java 自动加载JAR文件并运行其中的类方法

    3. **加载类**:使用加载的类加载器,我们可以加载JAR中的类。例如,如果我们知道类名为`com.example.MyClass`,我们可以这样加载: ```java String className = "com.example.MyClass"; Class&lt;?&gt; clazz = ...

    java 类从哪个jar包加载的

    类加载器负责查找并加载类的字节码文件(.class文件),这些文件通常来自于JAR包。类加载的过程可以分为三个阶段:加载、验证、准备、解析和初始化。 1. **加载**:类加载器寻找并读取类的二进制数据,这个数据可能...

Global site tag (gtag.js) - Google Analytics