在运行时将jar文件下载并添加到类路径而不进行反射

时间:2014-12-23 14:58:55

标签: java reflection classpath classloader

我们有一个独立的java应用程序。此应用程序具有许多功能,但大多数客户只使用此功能的一小部分。我们希望仅使用" normal"来分发应用程序。至少第三方jar文件。 在eclipse项目中,所有外部jar文件都在类路径中。因此没有反映用于实现类。因此,当用户打算使用更高级的功能时,例如拍摄webcamera图片,我们将下载所有javacv jar文件,然后以某种方式将这些文件添加到classpath / classloader,然后再调用我们的类拍照。这可能吗?我已经为一个非常小的模块提供了一个可行的解决方案,它可以动态下载一些jar文件并将它们添加到自定义类加载器中,但是我必须痛苦地实现每个类并通过反射调用每个方法。例如:

URLClassLoader loader = new URLClassLoader(urls,w.getClass().getClassLoader());
Class grabberClass = Class.forName("org.bytedeco.javacv.FrameGrabber",true,loader);
Object grabber = grabberClass.getMethod("createDefault", int.class).invoke(null, 0);
grabberClass.getMethod("start", null).invoke(grabber, null);
//And so on...

这不是我们想要的。我们所有的源代码都很好,我不想通过把它变成反射调用来混淆它。但是,我如何使用旧代码并仍然能够在运行时添加jar文件?

1 个答案:

答案 0 :(得分:0)

没有必要反思。尝试在类路径中运行没有javacv jar文件的应用程序。如果您从未触摸过网络摄像头功能,并且您没有以单片方式编写应用程序,那么您应该没有任何问题,因为Java不会尝试加载类,除非并且直到其他类在代码中引用它(或继承自它,或在方法签名或字段类型中使用它。)

至于按需下载.jar文件,请考虑使用Java Web Start并将它们作为.jnlp文件中的延迟组件:

<!DOCTYPE jnlp PUBLIC "-//Sun Microsystems, Inc//DTD JNLP Descriptor 6.0.10//EN"
                      "http://java.sun.com/dtd/JNLP-6.0.10.dtd">
<jnlp version="1.6"
      codebase="http://www.example.com/ourstandaloneapp/"
      href="OurStandaloneApp.jnlp">
    <information>
        <title>Our Stand-alone App</title>
        <vendor>Example, Inc.</vendor>
        <homepage href="http://www.example.com/ourstandaloneapp/"/>
        <description>A stand-alone application with many capabilities.</description>
        <icon kind="default" href="standalone.gif"/>
        <offline-allowed/>
    </information>

    <security>
        <all-permissions/>
    </security>

    <resources>
        <j2se version="1.7+"/>
        <jar href="OurStandaloneApp.jar" main="true"/>
        <jar href="http://search.maven.org/remotecontent?filepath=org/bytedeco/javacv/0.10/javacv-0.10.jar"
             download="lazy"/>
    </resources>

    <application-desc/>
</jnlp>

不必从Web下载/安装Web Start应用程序。您实际上可以将它打包到CD或闪存驱动器上,在执行javaws -codebase file:/path/to/media -import OurStandAloneApp.jnlp的安装介质上使用快捷方式或脚本。有关详细信息,请参阅here。 (为什么该页面已被删除用于Java 6及更高版本,我不知道。这非常有价值。)