我使用ASM更新的類棧地圖,但是當ASM getMergedType
,會出現以下異常:問題與ASM getMergedType和getCommonSuperClass
了java.lang.RuntimeException:
產生java.io.IOException:資源沒有找到IntefaceImplA。
如果沒有asm修改類方法,它確實工作正常。
我已經定義了兩個接口A和B:IntefaceImplA
和 IntefaceImplB
。
我的環境的源代碼:
IntefaceA.java
public interface IntefaceA {
void inteface();
}
IntefaceImplA.java
public class IntefaceImplA implements IntefaceA {
@Override
public void inteface() {
}
}
IntefaceImplB.java
public class IntefaceImplB implements IntefaceA {
@Override
public void inteface() {
}
}
Test.java
public class Test {
public IntefaceA getImpl(boolean b) {
IntefaceA a = b ? new IntefaceImplA() : new IntefaceImplB();
return a;
}
}
Main.java
public class Main {
public static void main(String args[]) {
....
if (a instance of Test) {
..
...
}
}
}
我編一個亞軍罐子後,並刪除IntefaceImplA.class和IntefaceA從jar中手動.class。爲什麼我想刪除這些類文件,因爲春天總是喜歡做這個東西。
runner jar可以在沒有ASM的情況下正常運行,但使用asm會發生異常。因爲asm想要爲IntefaceImplA和IntefaceImplB獲取MergeType,但IntefaceImplA被我刪除。 調查後,ASM ClassWriter源代碼,我發現下面的代碼:
protected String getCommonSuperClass(String type1, String type2)
{
ClassLoader classLoader = this.getClass().getClassLoader();
Class c;
Class d;
try {
c = Class.forName(type1.replace('/', '.'), false, classLoader);
d = Class.forName(type2.replace('/', '.'), false, classLoader);
} catch (Exception var7) {
throw new RuntimeException(var7.toString());
}
if(c.isAssignableFrom(d)) {
return type1;
} else if(d.isAssignableFrom(c)) {
return type2;
} else if(!c.isInterface() && !d.isInterface()) {
do {
c = c.getSuperclass();
} while(!c.isAssignableFrom(d));
return c.getName().replace('.', '/');
} else {
return "java/lang/Object";
}
}
其實,我刪除了相關的類文件,類加載器無法找到類。但程序沒有正常工作。
我應該增強對getCommonSuperClass方法的覆蓋,如果發生異常,那麼返回java/lang/Object?這很有趣
1.)爲什麼「使用ASM更新類堆棧映射」?沒有理由更新堆棧映射,除非您執行了其他代碼轉換。但是如果您執行其他代碼轉換,則這些轉換是ASM的主要用途,而不是更新堆棧映射。你應該說一些關於實際的目標。 2)爲什麼你會刪除仍然被代碼引用的類? 「因爲春天總是喜歡做這個東西」並不是一個有意義的解釋。 – Holger
因爲我需要在運行時插入一些代碼。 –
由於在使用tomcat作爲嵌入容器時,彈簧引導刪除了代碼以減小jar大小。 爲什麼「使用ASM更新類堆棧映射」?---我需要在運行時插入一些代碼。 –