텍스트 파일에 java 소스 코드가 있습니다. 사용자 정의 하드 코딩 된 변수를 소스 코드에 입력 한 다음 항아리로 변환해야합니다. 이것은 작동하지만 항아리를 실행할 때 Main 클래스를 찾을 수 없습니다.Java 프로그래밍 방식으로 jar를 컴파일
WinRAR을 사용하여 jar 파일을 추출 할 때 오류가없는 것 같습니다. 내가 cmd를 통해 생성/추출 된 클래스 파일을 실행하면
, 내가 얻을 "오류 : 주 클래스 홈페이지를 찾거나로드 할 수 없습니다"
매니페스트 생성 :
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;
}
}
}
자바 소스 코드가 포함 된 텍스트 파일 :
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 클래스를 사용하고 있습니다. 어느 쪽이 효과가 있긴하지만, 병 속에 담는 데 여전히 문제가 있습니다.
당신이 포함하고있는 클래스의 주요 방법이 있습니까 사용에 대한? 그것이 유일한 클래스가 포함되어 있다면, 그 항아리를 실행할 수없는 이유입니다. –
@ NathanielFord 텍스트 파일의 내용을 추가했습니다. – Reinard
패키지 선언을 텍스트 파일 (javabinder 패키지)에 추가하려고했지만 도움이되지 않았습니다. – Reinard