2009-12-31 20 views
113

olduğunu belirleme Hemen bir IDE'nin önünde değilim, yalnızca API teknik özelliklerine bakıyorum.Bir sınıf hangi JAR dosyasının

CodeSource src = MyClass.class.getProtectionDomain().getCodeSource(); 
if (src != null) { 
    URL jar = src.getLocation(); 
} 

Bir sınıfın hangi JAR dosyasının olduğunu belirlemek istiyorum. Bunu yapmanın yolu bu mu?

+0

konsoldan bunu yapmanın bir yolu var mı? Java -findjar -cp /some/path/with/libs/*.jar my.java.Class' -> 'my.jar' gibi bir şey. – kub1x

cevap

148

Evet. Bootstrap sınıf yükleyicisi tarafından yüklenen sınıflar dışındaki tüm sınıflar için çalışır. belirlemek için başka bir yoludur: notnoop işaret

Class klass = String.class; 
URL location = klass.getResource('/' + klass.getName().replace('.', '/') + ".class"); 

olarak getProtectionDomain().getCodeSource().getLocation() yöntem sınıf dosyasının kendisini konumunu döndürür. Örneğin:

jar:file:/jdk/jre/lib/rt.jar!/java/lang/String.class 
file:/projects/classes/pkg/MyClass$1.class 

klass.getResource() yöntem kavanoz dosya veya

file:/Users/home/java/libs/ejb3-persistence-1.0.2.GA.jar 
file:/projects/classes 
+0

Bu, varsayımların eşleştirmeyi sınıf adından sınıf dosyasına geçirmesine neden olur. Anonim sınıflar için uygun şekilde çalışacak mı? İç içe geçmiş sınıflar? –

+1

Bu, sınıfın url'sinin jar'ın kendisinden değil. Kavanoz dosyasını bulmak için URL'nin ayrıştırılması gerekir. – notnoop

+0

@ notnoop. Cevabı açıklığa kavuştum. –

11

Ödeme Lombok Patcher LiveInjector.java den LiveInjector.findPathJar() CLASSPATH'e konumunu döndürür. Dosyanın bir kavanozda gerçekte yaşamadığı ve bunu değiştirmek isteyebileceğiniz özel durumlar olduğunu unutmayın.

/** 
* If the provided class has been loaded from a jar file that is on the local file system, will find the absolute path to that jar file. 
* 
* @param context The jar file that contained the class file that represents this class will be found. Specify {@code null} to let {@code LiveInjector} 
*    find its own jar. 
* @throws IllegalStateException If the specified class was loaded from a directory or in some other way (such as via HTTP, from a database, or some 
*        other custom classloading device). 
*/ 
public static String findPathJar(Class<?> context) throws IllegalStateException { 
    if (context == null) context = LiveInjector.class; 
    String rawName = context.getName(); 
    String classFileName; 
    /* rawName is something like package.name.ContainingClass$ClassName. We need to turn this into ContainingClass$ClassName.class. */ { 
     int idx = rawName.lastIndexOf('.'); 
     classFileName = (idx == -1 ? rawName : rawName.substring(idx+1)) + ".class"; 
    } 

    String uri = context.getResource(classFileName).toString(); 
    if (uri.startsWith("file:")) throw new IllegalStateException("This class has been loaded from a directory and not from a jar file."); 
    if (!uri.startsWith("jar:file:")) { 
     int idx = uri.indexOf(':'); 
     String protocol = idx == -1 ? "(unknown)" : uri.substring(0, idx); 
     throw new IllegalStateException("This class has been loaded remotely via the " + protocol + 
       " protocol. Only loading from a jar on the local file system is supported."); 
    } 

    int idx = uri.indexOf('!'); 
    //As far as I know, the if statement below can't ever trigger, so it's more of a sanity check thing. 
    if (idx == -1) throw new IllegalStateException("You appear to have loaded this class from a local jar file, but I can't make sense of the URL!"); 

    try { 
     String fileName = URLDecoder.decode(uri.substring("jar:file:".length(), idx), Charset.defaultCharset().name()); 
     return new File(fileName).getAbsolutePath(); 
    } catch (UnsupportedEncodingException e) { 
     throw new InternalError("default charset doesn't exist. Your VM is borked."); 
    } 
} 
+2

Bu çok basit bir şey elde etmek için çok karmaşık görünüyor. Sadece oturdum ve daha önce bulduklarımı denedim ve işe yarıyor gibi görünüyor. Sadece bir doğrulama istiyordum. –

+0

Eh. Kodunuz, bootclass yollarındaki dosyaları işlemez ve Chandra'nın çözümü, url dosyasını jar dosyasına değil, dosyaya döndürür, böylece jar dosyasını bulmak için yolu ayrıştırmanız gerekir. – notnoop

0
private String resourceLookup(String lookupResourceName) { 



    try { 

     if (lookupResourceName == null || lookupResourceName.length()==0) { 
      return ""; 
     } 
     // "/java/lang/String.class" 

     // Check if entered data was in java class name format 
     if (lookupResourceName.indexOf("/")==-1) { 
      lookupResourceName = lookupResourceName.replaceAll("[.]", "/"); 
      lookupResourceName = "/" + lookupResourceName + ".class"; 
     } 

     URL url = this.getClass().getResource(lookupResourceName); 
     if (url == null) { 
      return("Unable to locate resource "+ lookupResourceName); 

     } 

     String resourceUrl = url.toExternalForm(); 

     Pattern pattern = 
      Pattern.compile("(zip:|jar:file:/)(.*)!/(.*)", Pattern.CASE_INSENSITIVE); 

     String jarFilename = null; 
     String resourceFilename = null; 
     Matcher m = pattern.matcher(resourceUrl); 
     if (m.find()) { 
      jarFilename = m.group(2); 
      resourceFilename = m.group(3); 
     } else { 
      return "Unable to parse URL: "+ resourceUrl; 

     } 

     if (!jarFilename.startsWith("C:")){ 
      jarFilename = "/"+jarFilename; // make absolute path on Linux 
     } 

     File file = new File(jarFilename); 
     Long jarSize=null; 
     Date jarDate=null; 
     Long resourceSize=null; 
     Date resourceDate=null; 
     if (file.exists() && file.isFile()) { 

      jarSize = file.length(); 
      jarDate = new Date(file.lastModified()); 

      try { 
       JarFile jarFile = new JarFile(file, false); 
       ZipEntry entry = jarFile.getEntry(resourceFilename); 
       resourceSize = entry.getSize(); 
       resourceDate = new Date(entry.getTime()); 
      } catch (Throwable e) { 
       return ("Unable to open JAR" + jarFilename + " "+resourceUrl +"\n"+e.getMessage()); 

      } 

      return "\nresource: "+resourceFilename+"\njar: "+jarFilename + " \nJarSize: " +jarSize+" \nJarDate: " +jarDate.toString()+" \nresourceSize: " +resourceSize+" \nresourceDate: " +resourceDate.toString()+"\n"; 


     } else { 
      return("Unable to load jar:" + jarFilename+ " \nUrl: " +resourceUrl); 

     } 
    } catch (Exception e){ 
     return e.getMessage(); 
    } 


} 
+0

Yukarıdaki kod, yoldaki herhangi bir kaynağı bulacaktır. Bir kavanozda, kavanozda kavanozun boyutunu ve tarihini ve kaynağın kavanoz içindeki boyutunu ve tarihini yazdıracaktır. – Don

İlgili konular