2015-12-05 3 views
8

Я хотел бы найти или создать загрузчик классов Java, который загружает только системные классы, исключая любые классы в определенном приложением пути. Моя цель - использовать этот загрузчик классов для создания загрузчика классов, который загружается из определенного JAR-файла, разрешая системные классы с использованием системного загрузчика классов, но не загрязняя классы из JAR-файла любыми классами, определенными моим приложением.Нужен Java-системный загрузчик классов

До сих пор я не нашел способа создать системный загрузчик классов, который не использует частные API или не делает предположений о реализации Java. См. Код ниже, который работает в моей текущей среде, но делает нежелательные предположения.

Если нет возможности создать независимый от системы системный загрузчик классов, есть ли причина, почему нет? Я пытаюсь сделать плохую идею?

private ClassLoader createJarClassLoader(File f) 
{ 
    ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 
    if (systemClassLoader instanceof URLClassLoader) { 
     URLClassLoader cl = (URLClassLoader) systemClassLoader; 
     URL[] urls = cl.getURLs(); 
     List<URL> wantedURLs = new ArrayList<>(); 
     for (URL u : urls) { 
      if (isSystemURL(u)) { 
       wantedURLs.add(u); 
      } 
     } 
     try { 
      wantedURLs.add(f.toURI().toURL()); 
     } catch (MalformedURLException ex) { 
      return null; 
     } 
     return new URLClassLoader(wantedURLs.toArray(new URL[0]), null); 
    } 
    return null; 
} 

private boolean isSystemURL(URL u) 
{ 
    return u.getPath().contains("/jre/"); 
} 
+2

Почему вы пытаетесь это сделать? что вы пытаетесь достичь? – jtahlborn

+0

@jtahlborn Он очень четко изложил свои соображения: «Моя цель ...» – qqilihq

+1

@qqilihq - нет, ОП описал «что» он пытался достичь, а не «почему» – jtahlborn

ответ

1

Необходимо установить родительский ClassLoader как загрузочный класс ClassLoader. Вызовите getClassLoader() на объект java.lang.String, чтобы получить загрузчик ClassLoader и использовать его в своем конструкторе ClassLoader.

public class MyClassLoader extends URLClassLoader { 

    protected MyClassLoader(URL[] urls, ClassLoader parent) { 
     super(urls, parent); 
    } 

    static MyClassLoader getInstance(URL[] urls) { 
     ClassLoader parent = "".getClass().getClassLoader(); 
     return (new MyClassLoader(urls, parent)); 
    } 
} 

Представление загрузчик классов документирована как реализация зависимой

Некоторые реализации могут использовать нуль для представления загрузчика начальной загрузки класса. Этот метод [getClassLoader] возвращает null в таких реализациях, если этот класс был загружен загрузчиком класса загрузки.

но такая же формулировка применяется к родительскому ClassLoader в конструкторе ClassLoader, что означает, что это решение является переносным.

+0

Хотя он (в основном) работает в JDK 8, там не гарантирует, что загрузчик класса bootstrap знает обо всех классах на платформе Java; в модульном JDK, запланированном для JDK9, это определенно не будет. Более интересным вопросом является то, что null означает, когда он передается конструктору ClassLoader. Я не нашел спецификации того, что это значит, но, возможно, можно было бы определить, что подразумевает загрузчик классов, который точно знает классы на платформе Java, не больше и не меньше. –

Смежные вопросы