首页 | 互联网 | IT动态 | IT培训 | Cisco | Windows | Linux | Java | .Net | Oracle | 软件测试 | C/C++ | 嵌入式开发 | 存储世界 | 服务器
网络设备 | IDC | 安全 | 求职招聘 | 数字网校 | 网页设计 | 平面设计 | 技术专题 | 电子书下载 | 教学视频 | 源码下载 | 搜索 | 博客 | 论坛
中国IT实验室Linux频道
中国IT教育
Google
首页 资讯动态 认证考试 新手入门 核心技术 高级技术 J2EE J2ME Java&XML 开源技术 其他技术 RSS订阅 论坛 专题
您现在的位置: 中国IT实验室 >> Java >> 核心技术 >> 高级编程 >> 正文

Java的“静态库链接”

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

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

    <target name="-post-jar">
            <taskdef resource="proguard/ant/task.properties" classpath="${libs.proguard.classpath}" />
            <copyfile src="${dist.jar}" dest="${dist.dir}/pre.jar"/>
            <proguard warn="false" obfuscate="false">
                <libraryjar path="${java.home}/lib/rt.jar" />
                <injar path="${javac.classpath}" filter="!META-INF/MANIFEST.MF" />
                <injar path="${dist.dir}/pre.jar"/>
                <outjar path="${dist.jar}"/>
                <keep name="${main.class}">
                    <method name="main"/>
                </keep>
                <keep name="org.jdesktop.beansbinding.ext.BeanAdapterProvider"/>
                <keepclasseswithmembernames>
                    <method name="getServiceNames"/>
                </keepclasseswithmembernames>
                <keepclasseswithmembernames>
                    <method name="addPropertyChangeListener"/>
                </keepclasseswithmembernames>
            </proguard>
        </target>

     <target name="-post-jar">
             <taskdef resource="proguard/ant/task.properties" classpath="${libs.proguard.classpath}" />
             <copyfile src="${dist.jar}" dest="${dist.dir}/pre.jar"/>
             <proguard warn="false" obfuscate="false">
                 <libraryjar path="${java.home}/lib/rt.jar" />
                 <injar path="${javac.classpath}" filter="!META-INF/MANIFEST.MF" />
                 <injar path="${dist.dir}/pre.jar"/>
                 <outjar path="${dist.jar}"/>
                 <keep name="${main.class}">
                     <method name="main"/>
                 </keep>
                 <keep name="org.jdesktop.beansbinding.ext.BeanAdapterProvider"/>
                 <keepclasseswithmembernames>
                     <method name="getServiceNames"/>
                 </keepclasseswithmembernames>
                 <keepclasseswithmembernames>
                     <method name="addPropertyChangeListener"/>
                 </keepclasseswithmembernames>
             </proguard>
         </target>
    Netbeans自带ProGuard混淆器,libs.proguard.classpath就是ProGuard的位置。关掉了警告,因为我的应用共享了J2ME的库。关掉了混淆,这样更能看出去掉了哪些类。后面的keep只要看着ProGuard的提示加就可以了——既然是一一对应的解决方案,为什么ProGuard不提供个自动选项,期望能早日加上。


 

【责编:landy】

中国IT教育

相关产品和培训
文章评论
 友情推荐链接
 认证培训
 专题推荐

 ·关于Java框架技术专题
 ·XML全攻略技术专题
 ·JAVA开源技术介绍专题
 ·Java嵌入式开发之J2ME技术专题
 ·超前体验 Oracle 11g的5个新特性…
 ·揭密使用VB.NET的五个实用技巧
 ·Oracle和SQL Server常用函数对比专题…
 ·展现C#世界 C#程序设计专题…
 ·Java入门 Tomcat的配置技巧精华专题…
 ·Oracle RMAN物理备份技术详解…
 今日更新
 社区讨论
 博客论点
 频道精选
 Java 频道导航