java

位置:IT落伍者 >> java >> 浏览文章

Java的“静态库链接”


发布日期:2019年09月07日
 
Java的“静态库链接”

Java的库组织方式就是动态链接从一个Java的jar包运行有可能要接一堆classpath就知道和基于静态链接的C语言要实现动态链接要做额外的事情相似Java要想实现类似C的静态链接也要做很多额外的事

用类似Fat Jar的方法把所有的依赖库打包的最后的库中其实不是静态链接——C的静态链接只把需要的代码复制过来不是眉毛胡子一把抓按说以Java的思想静态链接不是很必要因此也就没有原生支持但实践和理论毕竟差距很远不是每个库都是标准库假设你从别人的库中引用了几个类为了支持你的程序你必须提供别人的库(假设这个库并不流行)再假设你自己写了一个库以后再开发类似的程序就从库中派生当然你不想把所有的代码都发行出去这个问题在Netbeans上更为明显Netbeans提供了一个swing框架用起来当然很方便但是当发行程序的时候你就会发现Netbeans很负责任的把依赖库放到发行目录的lib下居然有将近M(禁掉粗口)光写一个窗口就要M!

ProGuard不光是个混淆器它也能解决静态链接的问题用它自己的话说是 It detects and removes unused classes fields methods and attributes下面给出的是在Netbeans中用的Ant脚本修改项目的buildxml添加

<target name=postjar>

<taskdef resource=proguard/ant/taskproperties classpath=${libsproguardclasspath} />

<copyfile src=${distjar} dest=${distdir}/prejar/>

<proguard warn=false obfuscate=false>

<libraryjar path=${javahome}/lib/rtjar />

<injar path=${javacclasspath} filter=!METAINF/MANIFESTMF />

<injar path=${distdir}/prejar/>

<outjar path=${distjar}/>

<keep name=${mainclass}>

<method name=main/>

</keep>

<keep name=orgjdesktopbeansbindingextBeanAdapterProvider/>

<keepclasseswithmembernames>

<method name=getServiceNames/>

</keepclasseswithmembernames>

<keepclasseswithmembernames>

<method name=addPropertyChangeListener/>

</keepclasseswithmembernames>

</proguard>

</target>

<target name=postjar>

<taskdef resource=proguard/ant/taskproperties classpath=${libsproguardclasspath} />

<copyfile src=${distjar} dest=${distdir}/prejar/>

<proguard warn=false obfuscate=false>

<libraryjar path=${javahome}/lib/rtjar />

<injar path=${javacclasspath} filter=!METAINF/MANIFESTMF />

<injar path=${distdir}/prejar/>

<outjar path=${distjar}/>

<keep name=${mainclass}>

<method name=main/>

</keep>

<keep name=orgjdesktopbeansbindingextBeanAdapterProvider/>

<keepclasseswithmembernames>

<method name=getServiceNames/>

</keepclasseswithmembernames>

<keepclasseswithmembernames>

<method name=addPropertyChangeListener/>

</keepclasseswithmembernames>

</proguard>

</target>Netbeans自带ProGuard混淆器libsproguardclasspath就是ProGuard的位置关掉了警告因为我的应用共享了JME的库关掉了混淆这样更能看出去掉了哪些类后面的keep只要看着ProGuard的提示加就可以了——既然是一一对应的解决方案为什么ProGuard不提供个自动选项期望能早日加上

上一篇:Java程序性能优化(2)

下一篇:在JAVA中实现图形界面退出(已测试)