问题描述:
由于历史原因,系统采用了很早期的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 包冲突问题的办法。 WebSphere 中类加载器的层次结构 在 WebSphere 中,类加载器的层次结构是一个自上而下的分层结构,最上层是系统的...
4. **设置耳聋类加载器(Deaf ClassLoader)**:对于某些特定的JAR包,可以设置为“耳聋”模式,使其不响应父类加载器的请求,从而避免冲突。 5. **使用模块化(OSGi)**:如果应用是基于OSGi的,可以通过模块化...
解决 jar 包冲突问题需要深入了解 WAS 中类加载器的工作机制,并根据实际情况选择合适的解决方法。 本文还详细介绍了 WAS 中类加载器的层次结构,包括 JVM Class loader、WebSphere Extensions Class loader、...
Java采用双亲委派模型来处理类加载过程,这对于理解如何解决类路径冲突问题非常重要。 - **WAS红皮书**:官方发布的WAS红皮书提供了详细的类加载说明,包括如何配置类加载顺序等内容。这对于深入理解WAS的工作机制...
"websphere下部署CXF项目jar包冲突问题解决方式"这一主题聚焦于如何在IBM Websphere Application Server (WAS)中成功部署包含Apache CXF Web服务的WAR包,解决由于类加载导致的运行异常。 Apache CXF是一个流行的...
自JDK 1.2以来,JVM采用委托模式加载类,先由引导类加载器(Bootstrap ClassLoader)加载核心类,接着是由扩展类加载器(Extension ClassLoader)加载扩展类,最后由应用程序类加载器(AppClassLoader)加载用户类。...
为了解决这个问题,OSGi引入了模块化概念,每个模块(称为bundle)都有自己的类加载器,可以在同一环境中并行运行不同版本的库。 在"myself"工程中,我们创建了两个不同版本的“myself”jar包。每个jar包都包含了...
同时,使用动态加载可以避免类冲突,因为自定义类加载器可以拥有自己的命名空间。 总结来说,动态加载jar包是Java编程中的一种高级技巧,它使程序具备了高度的灵活性和可扩展性。通过自定义类加载器和反射机制,...
1. 使用`Class.forName()`或`ClassLoader.loadClass()`:通过这两个方法可以指定`jar`包中的类路径,让类加载器找到并加载类。例如,`ClassLoader.loadClass("com.example.MyClass", true)`,其中第一个参数是类全名...
解决jar包冲突的工具类jarjar-1.4.rar,jar包冲突解决方法,解决jar与jar冲突,jar与aar冲突,不想删除任何一个包,只能修改其中一个jar包包名即可解决,解决方法详细请看这篇文章: ...
标签“Java 动态加载”不仅涵盖了上述的基础知识,还可能涉及更高级的话题,如类加载器的线程安全、双亲委派模型的打破以及如何处理类加载冲突等。在实际项目中,这些知识对于构建复杂、可扩展的应用程序是必不可少...
5. **合理组织类加载器**:在应用服务器如Tomcat中,可以通过调整类加载策略,比如使用`WEB-INF/classes`优先加载,避免不同模块重复引入的jar包产生冲突。 6. **使用jar包管理工具**:例如,使用FatJar或者One-Jar...
- **使用类加载器策略**:例如,使用自定义类加载器来控制类的加载顺序,避免冲突。 - **升级或降级依赖**:选择一个兼容的版本,或者对所有依赖进行统一版本管理,例如采用最新稳定版。 总的来说,"jar包冲突检测...
- **类加载器策略**:某些应用服务器允许配置类加载器策略,例如优先加载某个`jar`包中的类,以此避免冲突。 3. **依赖管理**: - **统一版本**:尽可能使所有依赖项保持相同的版本,尤其是对有冲突的库。 - **...
4. **使用类加载器策略**:在某些情况下,可以通过自定义类加载器策略来处理冲突。不同的类加载器可以加载不同版本的相同类,从而避免冲突。 5. **模块化系统**:在Java 9及以上版本,你可以利用Jigsaw模块系统来更...
在Java编程环境中,动态加载jar包是一项重要的技术,...`CSClassLoaderUtil`是这样的类加载器的一个实例,它可能是用Java编写的一个实用工具类,具体实现细节可能包括jar文件的读取、类的加载以及双亲委派模型的遵循。
- **类加载器**:在使用jarjar处理后的jar包时,可能需要调整类加载器的策略,确保新的类路径能够正确地加载和解析类。 - **测试与验证**:对处理后的jar包进行充分的测试,确保所有功能都能正常工作,因为类的...
"jar包冲突检测工具"正是为了解决这个问题而设计的。 这个工具的主要功能是帮助开发者检测出项目中可能存在的jar包冲突。它的工作原理可能是通过遍历指定路径下的所有jar文件,然后对比每个jar中的类文件,找出具有...
3. **加载类**:使用加载的类加载器,我们可以加载JAR中的类。例如,如果我们知道类名为`com.example.MyClass`,我们可以这样加载: ```java String className = "com.example.MyClass"; Class<?> clazz = ...
类加载器负责查找并加载类的字节码文件(.class文件),这些文件通常来自于JAR包。类加载的过程可以分为三个阶段:加载、验证、准备、解析和初始化。 1. **加载**:类加载器寻找并读取类的二进制数据,这个数据可能...