2

ボタンが 1 つある簡単なテスト プログラムがあります。ユーザーがボタンをクリックすると、プログラムは Runnable JAR を作成することになっています。Runnable JAR は、Firefox で google.com を開く単純なプログラムです。プログラムには3つのクラスがあります。


1) メイン.java

 package test;

    public class Main {

        public static void main(String[] args) {

            Selenium.getGoogle();

        }

    } 

2) セレン.Java

package test;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

public class Selenium {

    public static void getGoogle () {
        WebDriver driver = new FirefoxDriver();
        driver.get("http://google.com");
    }

}

3) TestGUI.java

package test;

import javax.swing.*;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;


public class TestGUI extends JFrame implements ActionListener {

    private static final long serialVersionUID = 1L;

    public TestGUI() {

        setSize(200, 100);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
        /*
         * JButton.
         */
        JButton startButton = new JButton("Create Runnable JAR file ! ");
        add(startButton);
        startButton.addActionListener(this);
    }


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


    public void actionPerformed(ActionEvent e) {
        System.out.println("The Button Works");
        String file1ToCompile = "test" + java.io.File.separator + "Main.java";

        String file2ToCompile = "test" + java.io.File.separator + "Selenium.java";

        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

        int compilationResult = compiler.run(null, null, null, file1ToCompile, file2ToCompile);

        if (compilationResult == 0) {

            System.out.println("Compilation is successful");

        } else {
            System.out.println("Compilation Failed");
        }
    }
}

私は 2 つの主要なクラスを持っています。TestGUI.javaGUIが表示されるようにマニフェストに追加しました。ユーザーがボタンをクリックしたら、プログラムで と で構成される Runnable JAR を作成する必要がMain.javaありSelenium.javaます。

ただし、エラーが発生null pointer exceptionしますint compilationResult = compiler.run(null, null, null, file1ToCompile, file2ToCompile);

これどうやってするの?

4

2 に答える 2

7

JDKではなくJREを使用しているため、NullPointerException最も可能性が高いです。JDK をダウンロードしてビルドパスに追加します。

次に、ファイルをコンパイルしているだけです。次に、jar ファイルを作成し、それに .class ファイルを追加する必要があります。jar 内のパッケージ構造が同じであることが重要です。瓶には次のものも必要です。

マニフェスト ファイル

依存ジャー

クラスローダ

マニフェスト ファイルには、どのクラスにmainメソッドが含まれているか、およびクラスパスに関する情報が記述されています。明らかな理由から、依存する jar (セレン) も存在する必要があります。依存 jar にクラスをロードするには、クラスローダーが必要です。以下は私の実装です:

public void actionPerformed(ActionEvent e){
        System.out.println("The Button Works");
        String file1ToCompile = "src" + java.io.File.separator + "test" + java.io.File.separator + "Main.java";
        String file2ToCompile = "src" + java.io.File.separator + "test" + java.io.File.separator + "Selenium.java";
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        int compilationResult = compiler.run(null, null, null, file1ToCompile, file2ToCompile);
        if (compilationResult == 0) {
            System.out.println("Compilation is successful");
        } else {
            System.out.println("Compilation Failed");
        }

        Manifest manifest = new Manifest();
        manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
        manifest.getMainAttributes().put(new Name("Rsrc-Class-Path"), "./ selenium-server-standalone-2.39.0.jar");
        manifest.getMainAttributes().put(Attributes.Name.CLASS_PATH, ".");
        manifest.getMainAttributes().put(new Name("Rsrc-Main-Class"), "test.Main");
        manifest.getMainAttributes().put(Attributes.Name.MAIN_CLASS, "org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader");
        try{
            JarOutputStream target = new JarOutputStream(new FileOutputStream("output.jar"), manifest);
            add(new File("src" + java.io.File.separator + "test" + java.io.File.separator + "Main.class"), target);
            add(new File("src" + java.io.File.separator + "test" + java.io.File.separator + "Selenium.class"), target);
            add(new File("org"), target);
            add(new File("selenium-server-standalone-2.39.0.jar"), target);
            target.close();
        }catch(Exception ex){
            ex.printStackTrace();
        }
    }

    private void add(File source, JarOutputStream target) throws IOException
    {
        BufferedInputStream in = null;
        try
        {
            if (source.isDirectory())
            {
                String name = source.getPath().replace("\\", "/");
                if (!name.isEmpty())
                {
                    if (!name.endsWith("/"))
                        name += "/";
                    JarEntry entry = new JarEntry(name);
                    entry.setTime(source.lastModified());
                    target.putNextEntry(entry);
                    target.closeEntry();
                }
                for (File nestedFile: source.listFiles())
                    add(nestedFile, target);
                return;
            }

            JarEntry entry = null;

            if(source.getPath().contains("jarinjarloader")){
                entry = new JarEntry(source.getPath());
            }
            else if(source.getName().endsWith(".class")){
                entry = new JarEntry("test/"+source.getName());
            }else if(source.getName().endsWith(".classpath")){
                entry = new JarEntry(source.getName());
            }else if(source.getName().endsWith(".jar")){
                entry = new JarEntry(source.getName());
            }
            entry.setTime(source.lastModified());
            target.putNextEntry(entry);
            in = new BufferedInputStream(new FileInputStream(source));

            byte[] buffer = new byte[1024];
            while (true)
            {
                int count = in.read(buffer);
                if (count == -1)
                    break;
                target.write(buffer, 0, count);
            }
            target.closeEntry();
        }
        finally
        {
            if (in != null)
                in.close();
        }
    }

私はEclipsejarinjarloaderで実行可能なjarを作成し、orgフォルダーを抽出してプロジェクトディレクトリにコピーすることで取得したクラスローダーにEclipseを使用しました。

ここに画像の説明を入力

これにはわずかな問題がありますが、何か小さなものが欠けているのではないかと思います。クラスローダーファイルがjarと同じディレクトリにある場合、output.jarは正常に実行されます。現在、jar 内からクラスローダーを見つけられるように、これを修正しようとしています。

于 2014-02-14T20:33:32.673 に答える
0

これが答えです!コードの最後の部分をこのように見る必要があります。

File folder = new File("C://Users//YourUser//YourWorkspace//YourProject//bin");
File[] files = folder.listFiles();
File file=new File("C://Users//YourUser//Desktop//Examples.jar");
于 2014-05-05T19:54:58.097 に答える