<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Thinking in Java
    Java開發技巧與實踐
    posts - 9,comments - 6,trackbacks - 0

    一、問題

    當開啟 minimizeJar 后,精簡的Jar運行會出現如下錯誤:

    The image could not be loaded: FileImageDescriptor(location=class org.eclipse.jface.dialogs.TitleAreaDialog, name=images/title_banner.png)
    org.eclipse.jface.resource.DeviceResourceException: Unable to create resource FileImageDescriptor(location=class org.eclipse.jface.dialogs.TitleAreaDialog, name=images/title_banner.png)
            at org.eclipse.jface.resource.ImageDescriptor.createResource(ImageDescriptor.java:184)
            at org.eclipse.jface.resource.DeviceResourceManager.allocate(DeviceResourceManager.java:55)
            at org.eclipse.jface.resource.AbstractResourceManager.create(AbstractResourceManager.java:88)
            at org.eclipse.jface.resource.ResourceManager.createImageWithDefault(ResourceManager.java:195)
    …………

    出現這個錯誤的直接現象是所有的圖片——包括圖標——都無法正確顯示。

    二、分析

    開始以為是resources打包錯誤導致沒有被壓進jar包,不過分析jar包內容發現并沒有文件缺失,然后開始分析minimizeJar的機制。文檔上說:

    <minimizeJar>
    When true, dependencies will be stripped down on the class level to only the transitive hull required for the artifact. Note: Usage of this feature requires Java 1.5 or higher.

    由此來看,shade做的只是做了靜態調用分析,并沒有做動態類加載運行分析,因此極大可能問題是出在這里了。而且從拋出的異常來看,有可能是圖片文件格式無法解析導致了圖片資源創建失敗。

    那么之后的調試方法就簡單了,首先上verbose大法,直接加verbose:class參數,分別運行正常的和異常的Jar包,從輸出信息發現了端倪:

    [Loaded java.lang.IndexOutOfBoundsException from C:\Program Files\Java\jre1.8.0_151\lib\rt.jar]
    [Loaded java.lang.ArrayIndexOutOfBoundsException from C:\Program Files\Java\jre1.8.0_151\lib\rt.jar]
    [Loaded org.eclipse.swt.internal.image.WinBMPFileFormat from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.swt.internal.image.GIFFileFormat from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.swt.internal.image.WinICOFileFormat from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.swt.internal.image.JPEGFileFormat from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.swt.internal.image.JPEGSegment from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.swt.internal.image.JPEGFixedSizeSegment from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.swt.internal.image.JPEGStartOfImage from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.swt.internal.image.PNGFileFormat from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.swt.internal.image.PngInputStream from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.swt.internal.image.PngDecodingDataStream from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.swt.internal.image.PngChunkReader from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.swt.internal.image.PngChunk from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.swt.internal.image.PngIhdrChunk from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.swt.internal.image.PngFileReadState from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.swt.internal.image.PngPlteChunk from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.swt.internal.image.PngIdatChunk from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.swt.internal.image.PngIendChunk from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.swt.internal.image.PngTrnsChunk from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.swt.internal.win32.BITMAPINFOHEADER from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.jface.window.ToolTip$ToolTipOwnerControlListener from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.jface.window.ToolTip$$Lambda$19/1873653341 from org.eclipse.jface.window.ToolTip]
    [Loaded org.cncert.xac.utils.ResourceManager from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.swt.widgets.ToolItem from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.swt.internal.win32.TBBUTTON from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.jface.resource.AbstractResourceManager$RefCount from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.swt.layout.FormData from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.swt.layout.FormAttachment from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.jface.dialogs.TitleAreaDialog$1 from file:/E:/Temp/*****.jar]
    [Loaded org.eclipse.jface.window.ToolTip$TooltipHideListener from file:/E:/Temp/*****.jar]

    注意上方紅色的字體,在異常的Jar包輸出中是沒有的,同時檢查了Jar包中果然沒有打包這幾個類!將這幾個類手動加入Jar包后,異常的Jar包可以正常運行了。

    從源代碼看,這幾個類型是SWT在運行時動態加載的,由 org.eclipse.swt.internal.image.FileFormat 動態加載,相關代碼如下:

    package org.eclipse.swt.internal.image;


    import java.io.*;

    import org.eclipse.swt.*;
    import org.eclipse.swt.graphics.*;

    /**
     * Abstract factory class for loading/unloading images from files or streams
     * in various image file formats.
     *
     
    */
    public abstract class FileFormat {
        static final String FORMAT_PACKAGE = "org.eclipse.swt.internal.image"; //$NON-NLS-1$
        static final String FORMAT_SUFFIX = "FileFormat"; //$NON-NLS-1$
        static final String[] FORMATS = {"WinBMP", "WinBMP", "GIF", "WinICO", "JPEG", "PNG", "TIFF", "OS2BMP"}; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$//$NON-NLS-5$ //$NON-NLS-6$//$NON-NLS-7$//$NON-NLS-8$

        LEDataInputStream inputStream;
        LEDataOutputStream outputStream;
        ImageLoader loader;
        int compression;

    static FileFormat getFileFormat (LEDataInputStream stream, String format) throws Exception {
        Class<?> clazz = Class.forName(FORMAT_PACKAGE + '.' + format + FORMAT_SUFFIX);
        FileFormat fileFormat = (FileFormat) clazz.getDeclaredConstructor().newInstance();
        if (fileFormat.isFileFormat(stream)) return fileFormat;
        return null;
    }

    三、Maven配置的修改

    在官方文檔中,可以使用filter來顯式包含不想被minimizeJar優化掉的內容,但是目前filter還無法做到針對一個artifact中選擇性對某個目錄下的文件不做優化。
    例如,我希望shade不對org/eclipse/swt/internal/image/**做優化,我的配置是這樣的:

    <filter>
         <artifact>org.eclipse:swt.win32.x86_64</artifact>
         <includes>
              <include>org/eclipse/swt/internal/image/**</include>
         </includes>
    </filter>

    但最終的結果是只打包了這個目錄內的類,而這個artifact中的其他類全部被removed,因為官方demo中有這樣一句話:

    As of version 1.6, minimizeJar will respect classes that were specifically marked for inclusion in a filter. Note that specifying an include filter for classes in an artifact implicitly excludes all non-specified classes in that artifact.

    所以我只能讓shade將swt的artifact全部保留,不做優化。

    <filter>
           <artifact>org.eclipse:swt.win32.x86_64</artifact>
           <includes>
                    <include>**</include>
           </includes>
    </filter>

    或者使用artifactSet達到同樣的效果。

    四、總結

    1. 目前shade的機制是靜態分析,所以可能會優化掉很多動態加載的類,對于使用動態加載較多的工程,在發布時需要特別注意。
    2. 目前shade的配置無法在一個artifact內顯式指定某個路徑不優化(或許有,但我確實沒找到,歡迎知道的朋友留言告知),只能顯式保留整個artifact不做優化。


    無人分享的快樂不是真快樂,沒人分擔的痛苦是真痛苦。
    posted on 2019-04-29 16:33 Feenn 閱讀(786) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發表評論。


    網站導航:
    博客園   IT新聞   Chat2DB   C++博客   博問  
     
    主站蜘蛛池模板: 花蝴蝶免费视频在线观看高清版| 免费人成黄页在线观看日本| 91香蕉成人免费网站| 久久久久亚洲AV成人无码| 三级毛片在线免费观看| 国产免费AV片无码永久免费| 久久精品国产亚洲AV| 精品久久免费视频| 成a人片亚洲日本久久| 亚洲国产午夜中文字幕精品黄网站 | 国产免费啪嗒啪嗒视频看看| 中文无码亚洲精品字幕| 国内外成人免费视频| 亚洲午夜成人精品无码色欲| 日本免费中文字幕在线看| 老司机午夜精品视频在线观看免费| 国产一区二区三区免费| 欧洲亚洲国产清在高| 老司机69精品成免费视频| 精品国产亚洲一区二区在线观看| 亚洲av日韩av激情亚洲| 日韩免费在线观看视频| 亚洲一区免费观看| 黄色片在线免费观看| 亚洲一区二区三区丝袜| 亚洲国产精品免费观看| 亚洲一区二区三区四区视频| 可以免费看黄的网站| 亚洲av永久无码精品网址| 又黄又大又爽免费视频| 免费国产草莓视频在线观看黄| 四虎国产精品免费永久在线| 亚洲国产一成人久久精品| 亚洲免费人成在线视频观看| 久久亚洲AV成人无码电影| 九九精品免费视频| 久久精品国产亚洲AV| 久久青草亚洲AV无码麻豆| 精选影视免费在线 | 婷婷久久久亚洲欧洲日产国码AV| 真人无码作爱免费视频|