[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);
        }

  

posted @ 2020-07-03 21:18  vanlin  阅读(197)  评论(0)    收藏  举报