2010-06-24 3 views
3

런타임시 현재 Jar 파일의 컴파일 된 클래스 (.class 파일)를 디렉토리 (패키지)에 추가하려고합니다.
어떻게 할 수 있습니까?Java : 런타임에 Jar 아카이브에 클래스 추가

감사

+2

왜 런타임에? 클래스 패스에 클래스를 추가하는 대신 jar 파일에 추가하는 이유는 무엇입니까? 아이디어가 조금 이상해 보였기 때문에 나는 이것을 묻습니다. – YuppieNetworking

+0

이 클래스를 프로그램 용 플러그인으로 사용하고 프로그램이 패키지에서 플러그인을 읽습니다. 또한 프로그램이 하나의 jar 파일이어야합니다. – RYN

답변

7

이 작업을 수행 할 수 없습니다 - 당신은 새로운 하나를 생성하고 새 것으로 이전을 덮어 쓸 필요가 JAR 파일을 업데이트합니다. 다음은

당신이 할 것입니다 방법에 대한 샘플입니다

import java.io.*; 
import java.util.*; 
import java.util.zip.*; 
import java.util.jar.*; 

public class JarUpdate { 
    /** 
    * main() 
    */ 
    public static void main(String[] args) throws IOException { 
     // Get the jar name and entry name from the command-line. 

     String jarName = args[0]; 
     String fileName = args[1]; 

     // Create file descriptors for the jar and a temp jar. 

     File jarFile = new File(jarName); 
     File tempJarFile = new File(jarName + ".tmp"); 

     // Open the jar file. 

     JarFile jar = new JarFile(jarFile); 
     System.out.println(jarName + " opened."); 

     // Initialize a flag that will indicate that the jar was updated. 

     boolean jarUpdated = false; 

     try { 
     // Create a temp jar file with no manifest. (The manifest will 
     // be copied when the entries are copied.) 

     Manifest jarManifest = jar.getManifest(); 
     JarOutputStream tempJar = 
      new JarOutputStream(new FileOutputStream(tempJarFile)); 

     // Allocate a buffer for reading entry data. 

     byte[] buffer = new byte[1024]; 
     int bytesRead; 

     try { 
      // Open the given file. 

      FileInputStream file = new FileInputStream(fileName); 

      try { 
       // Create a jar entry and add it to the temp jar. 

       JarEntry entry = new JarEntry(fileName); 
       tempJar.putNextEntry(entry); 

       // Read the file and write it to the jar. 

       while ((bytesRead = file.read(buffer)) != -1) { 
        tempJar.write(buffer, 0, bytesRead); 
       } 

       System.out.println(entry.getName() + " added."); 
      } 
      finally { 
       file.close(); 
      } 

      // Loop through the jar entries and add them to the temp jar, 
      // skipping the entry that was added to the temp jar already. 

      for (Enumeration entries = jar.entries(); entries.hasMoreElements();) { 
       // Get the next entry. 

       JarEntry entry = (JarEntry) entries.nextElement(); 

       // If the entry has not been added already, add it. 

       if (! entry.getName().equals(fileName)) { 
        // Get an input stream for the entry. 

        InputStream entryStream = jar.getInputStream(entry); 

        // Read the entry and write it to the temp jar. 

        tempJar.putNextEntry(entry); 

        while ((bytesRead = entryStream.read(buffer)) != -1) { 
        tempJar.write(buffer, 0, bytesRead); 
        } 
       } 
      } 

      jarUpdated = true; 
     } 
     catch (Exception ex) { 
      System.out.println(ex); 

      // Add a stub entry here, so that the jar will close without an 
      // exception. 

      tempJar.putNextEntry(new JarEntry("stub")); 
     } 
     finally { 
      tempJar.close(); 
     } 
     } 
     finally { 
     jar.close(); 
     System.out.println(jarName + " closed."); 

     // If the jar was not updated, delete the temp jar file. 

     if (! jarUpdated) { 
      tempJarFile.delete(); 
     } 
     } 

     // If the jar was updated, delete the original jar file and rename the 
     // temp jar file to the original name. 

     if (jarUpdated) { 
     jarFile.delete(); 
     tempJarFile.renameTo(jarFile); 
     System.out.println(jarName + " updated."); 
     } 
    } 
} 
+0

하지만 Jar 파일은 zip 형식이므로 압축 파일에 파일을 추가 할 수 있습니다! – RYN

+0

@ Snigger WinZip 또는 7Zip을 사용하는 경우 Java가 아닙니다. –

+0

그들은 프로그램도 아닌가? – RYN

1

내가 아주 확실하지 않다 그러나 나는 그것이 JAR 파일에서 클래스를로드 할 수 생각하지 않습니다을 (현실을 foo.jar에 전화하자) 그런 다음 클래스가로드 된 동일한 JAR 파일을 수정하고 새 클래스를 추가 한 다음 클래스가 ClassLoader에서 찾을 것으로 기대하십시오.

나는 응용 프로그램 자체를 리팩토링하고 설명 된 단일 JAR 동작을 강제로 시도하는 것보다 (URLClassLoader 또는 다른 기술을 사용하여) 클래스를 동적으로로드 할 수있게 만들 것입니다.