Што Загрузнік класаў гуляе выкарыстанне пры кампіляцыі класаў з кампілятарам JDT?

Я спрабую напісаць Play убудова, які дадае банка файлы ў Play класы падчас выканання. Калі OnLoad завецца ён павінен загрузіць набор слоічкаў, каб кампілятар JDT можа выкарыстоўваць іх для дазволу залежнасцяў у класах прыкладанняў. Гэтыя файлы банка не ў стандарце Бібліятэцы/ каталог і, такім чынам, не загружаныя ў сістэмным шляху да класаў пры запуску прайгравання.

На самай справе загрузкі файла банку не праблема, я буду ўказваць кожную слоік файл мне трэба як URL, а затым перадаваць іх да экземпляра URLClassLoader .

Пасля таго, як шмат даследаванняў, я зрабіў здагадку, што загрузнік класаў, што Play выкарыстоўвае ў Play.classloader і мой першапачатковы план быў стварыць свой уласны загрузнік класаў, які пашырае Play.ApplicationClassloader . Гэты загрузнік класаў будзе выкарыстоўваць асобнік URLClassLoader знайсці класы да перадачы ў стандартнай функцыянальнасці ў Play.ApplicationClassloader . Я тады збіраўся замяніць Play загрузнік класаў з маім новым асобнікам:

Play.classloader = new MyExtensionClassLoader();

Праблема я удараючы ў тым, што кампілятар JDT, здаецца, не выкарыстоўвайце Play.classloader асобніка, каб загрузіць гэта класы.

Таму ў мяне ёсць два пытанні:

Што шлях да класаў кампілятар JDT фактычна выкарыстоўваючы, калі ён не выкарыстоўваецца Play.classloader асобніка?

У больш агульным сэнсе, ці ёсць якія-небудзь прапановы, як я загружаю флягу у гульню падчас выканання, так што кампілятар JDT можа выкарыстоўваць яго?

1

2 адказы

Я не думаю, што будзе працаваць.

Гульня мае свой уласны загрузнік класаў, які спачатку правярае, калі клас «кіраваны клас прыкладання гульні» (той, які кампілюецца са асяроддзем выканання кампілятара JDT), то адкаты да бацькоўскага загрузніку, які па змаўчанні JVM-адзін ..

Такім чынам, усе playframework-класы ядра і іншыя бібліятэкі Hibernate-класы ўсе загружаюцца як звычайныя класы ад па змаўчанні Jvm-загрузніка класаў.

Я спадзяюся, што вы мяне разумееце :)

-morten

1
дададзена
Гэта мае сэнс. Як ужо згадвалася, я замяніў асобнік ApplicationClassloader , які знаходзіцца ў Play.classloader з маім уласным экземплярам. Я ведаю, што ён выклікаецца для класаў прыкладанняў, але здаецца, што кампілятар JDT не выкарыстоўвае гэты загрузнік класаў.
дададзена аўтар Matt Biggin, крыніца
Я выказаў меркаванне, што, замяніўшы Play.classloader , што ApplicationCompiler.compile() ... FindType() будзе выкарыстоўваць мой новы асобнік для загрузкі класаў. Гэта не так, хоць. Я спадзяваўся, што уклініцца ў FindType() у гэтым раздзеле: «// Так гэта стандартны клас байт [] байт = Play.classloader.getClassDefinition (імя);" якая знаходзіцца на лініі 184-185 з ApplicationCompiler .
дададзена аўтар Matt Biggin, крыніца
Пасля таго, як трохі больш даследавання: Магія адбываецца ў «прыватным NameEnvironmentAnswer FindType (канчатковая назва String)» у ApplicationCompiler, які загружае байт Класс з дапамогай «Play.classloader.getClassDefinition (імя)", які INTURN выкарыстоўвае getResourceAsStream (імя) (якое па змаўчанні метад загрузнік класаў).
дададзена аўтар mbknor, крыніца
ствараючы новы адказ, так як каментар поле было занадта мала ..
дададзена аўтар mbknor, крыніца

Я думаю, ваша праблема ў тым, што вы не можаце змяніць які java.lang.Classloader з'яўляецца бацька-загрузнік класаў для ApplicationClassloader.

Калі вы паглядзіце ў канструктару вы бачыце, што ён заўсёды выбірае загрузнік класаў, які ApplicationClassloader.class быў загружаны с.

Калі б вы маглі адправіць бацька-загрузнік класы, як пары канструктару ApplicationClassloader, тады вы маглі б зрабіць гэта:

стварыць новы ClassloaderA пашырае java.lang.Classloader з бацькоўскім-загрузнікам класаў як віртуальнай машыны Java-змаўчанні. Тады ў ClassloaderA, перавызначыць findClass і getResourceAsStream шукаць у вашых JAR-файлах, перш чым шукаць у бацьках. то вы маглі б даць Play.classloader новага асобнік ApplicationClassloader з асобнікам ClassloaderA як яго бацькоўскім загрузнік.

Я думаю, што гэта зробіць Загрузнік класаў-hirarchy правільна ..

0
дададзена
Я дам, што падчас. Дзякуючы.
дададзена аўтар Matt Biggin, крыніца
Пара пытанняў. 1/Як я магу атрымаць JVM па змаўчанні загрузнік класаў? (<Код> Thread.currentThread (). GetContextClassLoader() ?) 2/Як стварыць новы асобнік ApplicationClassloader , так што ClassloaderA з'яўляецца яго бацька загрузнік класаў?
дададзена аўтар Matt Biggin, крыніца
У інтарэсах адказваючы на ​​мой уласны пытанне, таму што рабіць нешта проста быць ясна, лянівы, 1/Як атрымаць загрузнік класаў віртуальнай машыны Java па змаўчанні ..... яно можа быць вызначана ў сістэме уласнасці «java.system.class.loader» таму пры запуску вы можаце паказаць -D java.system.class.loader = MyCustomClassLoader
дададзена аўтар Matt Biggin, крыніца
Калі я кажу «па змаўчанні» загрузнік класаў я маю на ўвазе пачатковы загрузнік класаў, які загружае першыя класы (ці ўсё класы), перш чым мы пачнем trixing яго. Усе classobjects маюць реф да экземпляра загрузніка класаў ён быў загружаны, так Integer.class.getClassloader() вяртае асобнік загрузніка класаў-я кажу пра
дададзена аўтар mbknor, крыніца