[JAVA.Bug]ClassLoader引起的Bug
问题表现:
Idea Plugin中使用JGraphX抛出 ClassNotFoundException 导致mxGraph不支持拖拽功能
com.mxgraph.swing.util.mxGraphTransferable ClassNotFoundException
原因分析:
1.该功能在单独Swing中没有出现任何问题,排除类本身不正确
2.从异常堆栈上看异常出现在 mxGraphTransferable 类静态初始化 dataFlavor 静态属性时
/**
* Local Machine Reference Data Flavor.
*/
static {
try {
htmlFlavors = new DataFlavor[3];
htmlFlavors[0] = new DataFlavor("text/html;class=java.lang.String");
htmlFlavors[1] = new DataFlavor("text/html;class=java.io.Reader");
htmlFlavors[2] = new DataFlavor(
"text/html;charset=unicode;class=java.io.InputStream");
plainFlavors = new DataFlavor[3];
plainFlavors[0] = new DataFlavor(
"text/plain;class=java.lang.String");
plainFlavors[1] = new DataFlavor("text/plain;class=java.io.Reader");
plainFlavors[2] = new DataFlavor(
"text/plain;charset=unicode;class=java.io.InputStream");
stringFlavors = new DataFlavor[2];
stringFlavors[0] = new DataFlavor(
DataFlavor.javaJVMLocalObjectMimeType
+ ";class=java.lang.String");
stringFlavors[1] = DataFlavor.stringFlavor;
imageFlavors = new DataFlavor[2];
imageFlavors[0] = DataFlavor.imageFlavor;
imageFlavors[1] = new DataFlavor("image/png");
} catch (ClassNotFoundException e) {
log.log(Level.SEVERE, "Error initializing flavors", e);
}
try {
dataFlavor = new DataFlavor(DataFlavor.javaSerializedObjectMimeType
+ "; class=com.mxgraph.swing.util.mxGraphTransferable");
} catch (ClassNotFoundException e) {
log.log(Level.SEVERE, "Error initializing dataFlavor", e);
}
}
3.跟进 DataFlavor 初始化,DataFlavor会在其 initialize 方法中 调用 representationClass = DataFlavor.tryToLoadClass(rcn, classLoader);
经过分析在 DataFlavor会获取AppClassLoader 来加载mxGraphTransferable 类,我们知道Idea Plugin其实是使用 PluginClassLoader作类加载器,这里已经能断定是由于类加载器的原因导致加载失败。
解决方案:
1.经过检查 DataFlavor是可以使用自定义类加载器的(不得不佩服JAVA老前辈们,API设计得滴水不漏)。
2.修改mxGraphTransferable源码,从外部将当前 PluginClassLoader类加载器传入
try {
dataFlavor = new DataFlavor(DataFlavor.javaSerializedObjectMimeType
+ "; class=com.mxgraph.swing.util.mxGraphTransferable", null, mxClassLoaderUtil.classLoader);
} catch (ClassNotFoundException e) {
log.log(Level.SEVERE, "Error initializing dataFlavor", e);
}

浙公网安备 33010602011771号