现在的位置: 首页 > 综合 > 正文

Java的“静态库链接”

2013年07月27日 ⁄ 综合 ⁄ 共 1685字 ⁄ 字号 评论关闭

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,添加:

  1.  
    <
    target
     
    name
    =
    "-post-jar"
    >
  2.         
    <
    taskdef
     
    resource
    =
    "proguard/ant/task.properties"
     
    classpath
    =
    "${libs.proguard.classpath}"
     
    />
  3.         
    <
    copyfile
     
    src
    =
    "${dist.jar}"
     
    dest
    =
    "${dist.dir}/pre.jar"
    />
  4.         
    <
    proguard
     
    warn
    =
    "false"
     
    obfuscate
    =
    "false"
    >
  5.             
    <
    libraryjar
     
    path
    =
    "${java.home}/lib/rt.jar"
     
    />
  6.             
    <
    injar
     
    path
    =
    "${javac.classpath}"
     
    filter
    =
    "!META-INF/MANIFEST.MF"
     
    />
  7.             
    <
    injar
     
    path
    =
    "${dist.dir}/pre.jar"
    />
  8.             
    <
    outjar
     
    path
    =
    "${dist.jar}"
    />
  9.             
    <
    keep
     
    name
    =
    "${main.class}"
    >
  10.                 
    <
    method
     
    name
    =
    "main"
    />
  11.             
    </
    keep
    >
  12.             
    <
    keep
     
    name
    =
    "org.jdesktop.beansbinding.ext.BeanAdapterProvider"
    />
  13.             
    <
    keepclasseswithmembernames
    >
  14.                 
    <
    method
     
    name
    =
    "getServiceNames"
    />
  15.             
    </
    keepclasseswithmembernames
    >
  16.             
    <
    keepclasseswithmembernames
    >
  17.                 
    <
    method
     
    name
    =
    "addPropertyChangeListener"
    />
  18.             
    </
    keepclasseswithmembernames
    >
  19.         
    </
    proguard
    >
  20.     
    </
    target
    >

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

抱歉!评论已关闭.