我有一个关于保证的问题,如果有的话,在下面的场景中(请注意问题不是"如何以不同的方式做到这一点?"),问题实际上是关于以下情况下的类加载顺序(至更好地理解类加载的工作原理).
这是假设的场景......有一个.war文件,它具有以下(部分)目录结构:
WEB-INF/classes/com/acme/Bunny.class
.
.
.
WEB-INF/lib/acme.jar
Run Code Online (Sandbox Code Playgroud)
两个Bunny.class文件都有导入引用acme.jar中的其他类
Bunny.class在WEB-INF /班/ ...是具有相同的名称/路径,一个类从唯一的类acme.jar.
该的.jar文件acme.jar还包含com.acme.Bunny(也有使用没有特殊的类装载器的技巧).
我知道Java规范保证在程序实际使用(或者故意"手动加载")之前不会加载类,这就是为什么如果你填充成千上万的.jar,比如说.war,类加载器不会开始类加载数万个类.
(编辑)
但是上面示例中的两个类的加载顺序又如何呢?
应该措辞:
但是如何确定上面两个类中的哪一个被加载?
或类似的东西 :)
有做一个保证:com.acme.Bunny不得将任何其它类之前,使用com.acme ....
基本上,在维基百科上,写了以下内容:
最复杂的JAR地狱问题出现在利用类加载系统的完全复杂性的情况下.Java程序不需要仅使用单个"平面"类加载器,而是可以由几个(或实际上是无限数量)嵌套的协作类加载器组成.由不同类加载器加载的类可能以复杂的方式进行交互,而开发人员无法完全理解这些类,从而导致无法解释的错误或错误.
所以我想知道:我可以确定/classes/com/acme/Bunny.class是否会在WEB-INF/lib / dir中的.jar之前进行类加载?
我需要创建一个 java 代理,当启用它时,它将获取 jar 文件的路径作为参数,然后如果它们的名称匹配,它将替换 jar 文件中的任何加载类。
例如,我们有一个名为 com.something.ClassTest 的类的应用程序。现在,如果提到的 jar(不在类路径中)有一个与 com.something.ClassTest 同名的类,我想用 jar 中的那个来替换它。
我有这个类转换器,但不确定这是否正确。我收到消息 Class not found 的 IOException。
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
if(classNames.contains(className.replace("/", "."))) {
System.out.format("\n==> Found %s \n", className);
try {
Class c = urlClassLoader.loadClass(className.replace("/", "."));
InputStream is = urlClassLoader.getResourceAsStream(className.replace("/", "."));
System.out.println("Loaded class " + c);
ClassReader reader = new ClassReader(is);
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
byte[] content = writer.toByteArray();
System.out.println("Redifned …Run Code Online (Sandbox Code Playgroud)