如何在java程序中从非可运行的JAR中调用类? [英] How to call a class from non-runnable JAR in java program?

查看:169
本文介绍了如何在java程序中从非可运行的JAR中调用类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑一下 - 我有一个名为TestApplication的简单一类应用程序(下面的源代码):

  import javafx .application.Application; 
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

公共类TestApplication扩展Application {

public Parent createContent(){

/ * layout * /
BorderPane layout = new BorderPane ();

/ * layout - > center * /
按钮按钮=新按钮(运行JAR);
button.setOnAction(new EventHandler< ActionEvent>(){
@Override
public void handle(ActionEvent ae){
//从TestJar.jar调用TestJar.class
}
});

/ *将项目添加到布局* /
layout.setCenter(按钮);
返回布局;
}

@Override
public void start(阶段阶段)抛出异常{
stage.setScene(new Scene(createContent()));
stage.setWidth(200);
stage.setHeight(200);
stage.show();
}

public static void main(String args []){
launch(args);
}
}

现在,在其按钮中.setOnAction()方法我想调用一个TestJar.class(扩展javafx.stage.Stage),这是唯一一个不可运行的TestJar.jar存档类。但问题是,我希望能够从TestApplication级别调用TestJar.class而无需事先将代码添加到代码中。例如,我有一个应用程序,我提供jar位置和有关此jar中类的名称的信息,应该调用它。下面的TestJar.java类的代码:

  import javafx.scene.Scene; 
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

公共类TestJar扩展Stage {

public TestJar(){
super();
BorderPane layout = new BorderPane();
Label label = new Label(This is test);
layout.setCenter(label);
场景场景=新场景(布局,200,200);
this.setScene(场景);
this.show();
}
}

另外还有JAR文件的结构:

 < archive = TestJar.jar> 
< folder = META-INF>
< file = MANIFEST.MF>
清单 - 版本:1.0
< / file>
< / folder>
< file = .classpath>
<?xml version =1.0encoding =UTF-8?>
< classpath>
< classpathentry kind =srcpath =src/>
< classpathentry kind =conpath =org.eclipse.jdt.launching.JRE_CONTAINER/>
< classpathentry kind =outputpath =bin/>
< / classpath>
< / file>
< file = .project>
<?xml version =1.0encoding =UTF-8?>
< projectDescription>
< name> TestJar< / name>
< comment>< / comment>
< projects>
< / projects>
< buildSpec>
< buildCommand>
< name> org.eclipse.jdt.core.javabuilder< / name>
< arguments>
< / arguments>
< / buildCommand>
< / buildSpec>
< natures>
< nature> org.eclipse.jdt.core.javanature< / nature>
< / natures>
< / projectDescription>
< / file>
< file = TestJar.class>< / file>
< / archive>

有什么方法可以从我的TestApplication类中可编程调用TestJar类吗? / p>

UPDATE 2014/07 / 26,11:37 AM



我用过@Allain Lalonde在中编写的示例如何在运行时动态加载Jars ?名为 ClassPathHack



接下来,我将他的解决方案与@Doswell在本主题中提出的建议合并,看起来像这个:

  button.setOnAction(new EventHandler< ActionEvent>(){
@Override
public void handle(ActionEvent ae){
try {
ClassPathHack.addFile(C:/ Users / John Smith / Desktop / TestJar.jar);

Class<?> clazz = Class.forName(TestJar);
Stage testJar =(Stage)clazz.newInstance();

} catch(IOException e ){
e.printStackTrace();
} catch(ClassNotFoundException e){
e.printStackTrace();
} catch(InstantiationException e){
e.printStackTrace();
} catch(IllegalAccessException e){
e.printStackTrace();
}
}
})

一切都很完美。谢谢!

解决方案

如果您要从jar运行的类扩展/实现您在代码中已知的内容可以使用反射加载类,但可以使用它,就像你知道的那样,即javafx.stage.Stage vs TestJar。



如果JAR已经在类路径中你可以做;

 类<?> clazz = Class.forName(TestJar); 
阶段testJar =(阶段)clazz.newInstance();

如果类路径上没有JAR,但确实有jar的路径,你可以按照这个我该如何加载一个罐子
然后加载上面的类


Consider this - I have a simple one-class application called "TestApplication" (source code below):

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class TestApplication extends Application {

    public Parent createContent() {

        /*layout*/
        BorderPane layout = new BorderPane();

        /*layout -> center*/
        Button button = new Button("Run JAR");
        button.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent ae) {
                // Call TestJar.class from TestJar.jar
            }
        });

        /*add item to the layout*/
        layout.setCenter(button);
        return layout;
    }

    @Override
    public void start(Stage stage) throws Exception {
        stage.setScene(new Scene(createContent()));
        stage.setWidth(200);
        stage.setHeight(200);
        stage.show();
    }

    public static void main(String args[]) {
        launch(args);
    }
}

Now, in its button.setOnAction() method I want to call a "TestJar.class" (extends javafx.stage.Stage), which is the only class of non-runnable "TestJar.jar" archive. But problem is, I want to be able to call "TestJar.class" from the level of "TestApplication" without the prior possibility of adding imports to the code. For example I have an application, for which I provide jar location and information about the name of the class in this jar, which should be call out. Code of the "TestJar.java" class below:

import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class TestJar extends Stage {

    public TestJar() {
        super();
        BorderPane layout = new BorderPane();
        Label label = new Label("This is test");
        layout.setCenter(label);
        Scene scene = new Scene(layout, 200, 200);
        this.setScene(scene);
        this.show();
    }
}

And additionaly structure of the JAR file:

<archive = TestJar.jar>
    <folder = META-INF>
        <file = MANIFEST.MF>
            Manifest-Version: 1.0
        </file>
    </folder>
    <file = .classpath>
        <?xml version="1.0" encoding="UTF-8"?>
        <classpath>
            <classpathentry kind="src" path="src"/>
            <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
            <classpathentry kind="output" path="bin"/>
        </classpath>
    </file>
    <file = .project>
        <?xml version="1.0" encoding="UTF-8"?>
        <projectDescription>
            <name>TestJar</name>
            <comment></comment>
            <projects>
            </projects>
            <buildSpec>
                <buildCommand>
                    <name>org.eclipse.jdt.core.javabuilder</name>
                    <arguments>
                    </arguments>
                </buildCommand>
            </buildSpec>
            <natures>
                <nature>org.eclipse.jdt.core.javanature</nature>
            </natures>
        </projectDescription>   
    </file>
    <file = TestJar.class></file>
</archive>

Is there any way I can call that "TestJar" class programmably from my "TestApplication" class?

UPDATE 2014/07/26, 11:37AM

I've used the example written by @Allain Lalonde in How should I load Jars dynamically at runtime? called ClassPathHack

Next, I've merged his solution with suggestion made in this topic by @Doswell, which looks like this:

button.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent ae) {
        try {
            ClassPathHack.addFile("C:/Users/John Smith/Desktop/TestJar.jar");

            Class<?> clazz = Class.forName("TestJar");
            Stage testJar = (Stage) clazz.newInstance();

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } 
    }
})

Everything works perfectly. Thank you!

解决方案

If the class you want to run from the jar extends/implements something you know about in your code already you can use reflection to load the class but work with it as whatever it is you know it as ie javafx.stage.Stage vs TestJar.

If the JAR is already on the classpath you can just do;

Class<?> clazz = Class.forName("TestJar");
Stage testJar = (Stage)clazz.newInstance();

If you don't have the JAR on the classpath, but do have the path to the jar, you can follow this How should I load a jar And then load the class as above

这篇关于如何在java程序中从非可运行的JAR中调用类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆