Java 以编程方式创建具有来自GUI的外部JAR的可运行JAR?
我有一个简单的测试程序,有一个按钮。当用户单击按钮时,程序应该创建一个可运行的JAR。Runnable JAR是一个在Firefox中打开google.com的简单程序。该课程分为三节课Java 以编程方式创建具有来自GUI的外部JAR的可运行JAR?,java,java-compiler-api,Java,Java Compiler Api,我有一个简单的测试程序,有一个按钮。当用户单击按钮时,程序应该创建一个可运行的JAR。Runnable JAR是一个在Firefox中打开google.com的简单程序。该课程分为三节课 1)Main.java package test; public class Main { public static void main(String[] args) { Selenium.getGoogle(); } }
1)Main.java
package test;
public class Main {
public static void main(String[] args) {
Selenium.getGoogle();
}
}
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");
}
}
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)Selenium.Java
package test;
public class Main {
public static void main(String[] args) {
Selenium.getGoogle();
}
}
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");
}
}
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");
}
}
}
3)TestGUI.java
package test;
public class Main {
public static void main(String[] args) {
Selenium.getGoogle();
}
}
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");
}
}
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");
}
}
}
我有两门主要课。我在清单中添加了TestGUI.java
,这样GUI就会显示出来。一旦用户单击该按钮,我希望我的程序创建一个可运行的JAR,它由Main.java
和Selenium.java
组成
但是,对于int compilationResult=compiler.run(null,null,null,file1ToCompile,file2ToCompile),我得到了一个错误null指针异常
代码>
我该怎么做呢?您得到的是NullPointerException
很可能是因为您使用的是JRE而不是JDK。一个JDK并将其添加到buildpath
其次,您只是在编译文件。然后需要创建一个jar文件,并将.class文件添加到其中。重要的是,它们在jar中具有相同的包结构。在罐子中,您还需要:
清单文件
从属罐子
类加载器
清单文件描述了哪个类包含类路径上的main
方法和信息。
由于明显的原因,也需要存在依赖性罐子(硒)。
需要一个类加载器来加载依赖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();
}
}
我使用Eclipse的jarinjarloader
作为我的类加载器,我在Eclipse中创建了一个可运行的jar,提取org
文件夹并将其复制到我的项目目录中
这有一个小问题,但我怀疑我遗漏了一些小东西。如果类加载器文件与jar位于同一目录中,output.jar将正常运行。我目前正在尝试修复此问题,以便它可以从jar中找到类加载器。是O.O最终找到它的答案!!您只需以这种方式查看代码的最后一部分:
File folder = new File("C://Users//YourUser//YourWorkspace//YourProject//bin");
File[] files = folder.listFiles();
File file=new File("C://Users//YourUser//Desktop//Examples.jar");
那就确定你的头衔吧。这与另一篇文章完全相同。如果作为错误粘贴的代码行是正确的,则您的编译器变量看起来是空的。因此,当您尝试对其调用.run()
时,它会抛出一个异常,因为没有人在家。你需要多带点东西来参加聚会;你不能真的从互联网上复制/粘贴一些你不懂的代码,然后期望我们向你解释它是如何工作的。“Once”是如何拼写“ones”。我试着编辑帖子来修正打字错误,但不让我这么做,因为改动“很小”。也许在角色中是这样,但大脑处理意思而不是说话所花费的时间并不是很小,至少对强迫症患者来说是这样的!:)NPE最有可能发生,因为您使用的是JRE而不是JDK和ToolProvider.getSystemJavaCompiler()
返回null而不是编译器实例。“从GUI以编程方式创建…不是一种矛盾修饰法吗?这是不正确的。答案只能从文件夹中找到。这不是一个真正的问题JAR@CHEBURASHKA我在回答的末尾解释了这一点。我正在努力修好它,你有什么想法吗?