|
|
|
ClassCastException кастомизации класслоадинга
|
|||
|---|---|---|---|
|
#18+
Почитал про класслоадинг в java и побаловался на примере. Один момент остался не ясен. Вот написал я свой кастомный класслоадер, парентом которого является System Classloader. также имеется интерфейс MyInterface и класс MyInterfaceImpl(имплементация этого интерфейса) пишу свой Main класс, в main которого, гружу MyInterface обычным образом то есть Системным класслоадером, а MyInterfaceImpl с помошью кастомного класслоадера. в этом же методе кастую MyInterfaceImpl к MyInterface. Всё ок. Если подгрузить MyInterfaceImpl тоже через кастомный класслоадер, то вываливается ClassCastException. Там где я это вычитал это подается как то, что Main не имеет доступа к MyInterfaceImpl так как они загружены разными класслоадерами. А почему скастить классы загруженный разными класслоадерами можно? в чем разница? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2017, 23:46 |
|
||
|
ClassCastException кастомизации класслоадинга
|
|||
|---|---|---|---|
|
#18+
questioner Там где я это вычитал это подается как то, что Main не имеет доступа к MyInterfaceImpl Вы опять читаете какую-то ерунду, либо странно её интерпретируете. Вопрос вообще не в доступе. Класс в JVM идентифицируется в том числе загрузчиком. Поэтом один и тот же класс с одним и тем же байт-кодом, загруженый разными загрузчиками, это формально два разных класса. Всё. questionerА почему скастить классы загруженный разными класслоадерами можно? в чем разница? Разница в том как грузится MyInterface. Либо он грузится один раз родительским, тогда дочерний загрузчик делегирует поиск родителю и использует класс загруженый им. Либо MyInterface грузится два раза, если загрузчик не имеет родителя, либо не делегирует ему поиск. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2017, 08:10 |
|
||
|
ClassCastException кастомизации класслоадинга
|
|||
|---|---|---|---|
|
#18+
Blazkowicz, Blazkowicz Класс в JVM идентифицируется в том числе загрузчиком. Поэтом один и тот же класс с одним и тем же байт-кодом, загруженый разными загрузчиками, это формально два разных класса. Всё. Это понятно. Это я и раньше знал. BlazkowiczquestionerА почему скастить классы загруженный разными класслоадерами можно? в чем разница? Разница в том как грузится MyInterface. Либо он грузится один раз родительским, тогда дочерний загрузчик делегирует поиск родителю и использует класс загруженый им. Либо MyInterface грузится два раза, если загрузчик не имеет родителя, либо не делегирует ему поиск. Я приведу конкретный код: код кастомного загрузчика(его особенность в том, что он смотрит на маппинг и если маппинг присутствует, то будем грузить нашим лоадером): Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. класс и интерфейс: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. Код: java 1. 2. 3. 4. 5. содержимое main метода: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. output: авторloadClass (sur.che.SexyClassForLoader) with XLoader loadClass (sur.che.ISexyInterface) with XLoader loadClass (java.lang.Object) with parent classloader class was loaded with sur.che.XLoader@7f31245a loadClass (java.lang.System) with parent classloader loadClass (java.io.PrintStream) with parent classloader SexyClassForLoader$$static SexyClassForLoader$$init sur.che.XLoader@7f31245a sun.misc.Launcher$AppClassLoader@232204a1 Exception in thread "main" java.lang.ClassCastException: sur.che.SexyClassForLoader cannot be cast to sur.che.ISexyInterface at sur.che.Loader.main(Loader.java:25) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) Если закомментировать строку: Код: java 1. то ошибка не валится: авторloadClass (sur.che.SexyClassForLoader) with XLoader loadClass (sur.che.ISexyInterface) with parent classloader loadClass (java.lang.Object) with parent classloader class was loaded with sur.che.XLoader@7f31245a loadClass (java.lang.System) with parent classloader loadClass (java.io.PrintStream) with parent classloader SexyClassForLoader$$static SexyClassForLoader$$init sur.che.XLoader@7f31245a sun.misc.Launcher$AppClassLoader@232204a1 make ba ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2017, 13:18 |
|
||
|
ClassCastException кастомизации класслоадинга
|
|||
|---|---|---|---|
|
#18+
questionerЭто понятно. Это я и раньше знал. Вопрос тогда в чём? questionerЕсли закомментировать строку:то ошибка не валится: Вы оперируете понятиями "ошибка есть" и "ошибка нет". Это просто жесть какая-то. Поставьте брейк-поинт на строке где выбрасывается ClassCastException. Найдите ISexyInterface внутри sexy_ob.getClass().getInterfaces() и сравните его с ISexyInterface.class. Увидите два разных класса. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2017, 14:15 |
|
||
|
ClassCastException кастомизации класслоадинга
|
|||
|---|---|---|---|
|
#18+
BlazkowiczПоставьте брейк-поинт на строке где выбрасывается ClassCastException. Найдите ISexyInterface внутри sexy_ob.getClass().getInterfaces() и сравните его с ISexyInterface.class. Увидите два разных класса. авторsexy_ob.getClass().getInterfaces()[0].getClassLoader().getClass().getName() => sur.che.XLoader авторISexyInterface.class.getClassLoader().getClass().getName() => sun.misc.Launcher$AppClassLoader Да, это так, но как закомментированная строка то влияет на это поведение и почему? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2017, 14:52 |
|
||
|
ClassCastException кастомизации класслоадинга
|
|||
|---|---|---|---|
|
#18+
questionerДа, это так, но как закомментированная строка то влияет на это поведение и почему? Отладка через форум? Если класса нет в списке, XLoader его не грузит, а использует тот который у родителя. Выходит один экземпляр, а не два. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2017, 15:00 |
|
||
|
ClassCastException кастомизации класслоадинга
|
|||
|---|---|---|---|
|
#18+
сильно в коде не копался, но у вас есть строка Код: java 1. Предполагаю, что когда грузится класс мейн, то у вас там его импорт, потому он и грузится системным загрузчиком. Вам или грузить мэйн кастомным класслоадером или не делать жестких импортов ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2017, 15:01 |
|
||
|
ClassCastException кастомизации класслоадинга
|
|||
|---|---|---|---|
|
#18+
забыл никсильно в коде не копался, но у вас есть строка Код: java 1. Предполагаю, что когда грузится класс мейн, то у вас там его импорт, потому он и грузится системным загрузчиком. Вам или грузить мэйн кастомным класслоадером или не делать жестких импортов Следующая строка Код: java 1. Точно так же заставит AppClassLoader грузить интерфейс. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2017, 15:07 |
|
||
|
ClassCastException кастомизации класслоадинга
|
|||
|---|---|---|---|
|
#18+
в итоге получается, что: Что явная загрузка класса ведет к загрузке интерфейса. Если строка Код: java 1. закомментирована, то кастомный лоадер загрузить не сможет и будет использоваться лоадер приложения. При попытке скастить используется интерфейс, который явно загружен лоадером нашего приложения и интерфейс, загруженный при загрузке класса. Соответственно если строку раскомментировать, то будем сравнивать интерфейс загруженный нашим лоадером и интерфейс, загруженный лоадером приложения. так? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2017, 15:22 |
|
||
|
ClassCastException кастомизации класслоадинга
|
|||
|---|---|---|---|
|
#18+
questioner, Вы путаете логику своего странноватого кода и логику загрузки. 1) Class sexy_cla = xloa.loadClass("sur.che.SexyClassForLoader"); - насильно требуем загрузить класс 2) Класс реализует интерфейс, значит надо загрузить и интерфейс. 3) Грузим тем же XLoader, в котором нет делегации родителю, если интерфейс указан в списке mappings. Итого имеем оба класса загружены XLoader-ом. Родитель - AppClassLoader про XLoader ничего не знает. Поэтому тоже грузит ISexyInterface, так как он используется в методе. Я бы посоветовал прочитать исходный код класса ClassLoader. Хотя бы метода loadClass(String, boolean). Но как мы выяснили в прошлой теме, это очень сложно. Так что, вероятно, совет лишен смысла. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2017, 15:32 |
|
||
|
ClassCastException кастомизации класслоадинга
|
|||
|---|---|---|---|
|
#18+
Blazkowiczquestioner, Вы путаете логику своего странноватого кода и логику загрузки. 1) Class sexy_cla = xloa.loadClass("sur.che.SexyClassForLoader"); - насильно требуем загрузить класс 2) Класс реализует интерфейс, значит надо загрузить и интерфейс. 3) Грузим тем же XLoader, в котором нет делегации родителю, если интерфейс указан в списке mappings. Итого имеем оба класса загружены XLoader-ом. Родитель - AppClassLoader про XLoader ничего не знает. Поэтому тоже грузит ISexyInterface, так как он используется в методе. Я бы посоветовал прочитать исходный код класса ClassLoader. Хотя бы метода loadClass(String, boolean). Но как мы выяснили в прошлой теме, это очень сложно. Так что, вероятно, совет лишен смысла. Так я то же самое и написал. разве нет? когда пытаемся скастить к интерфейсу ведь наверное просматриваются getInterfaces() и получается, что интерфейсы разные по той причине, что загружены разными лоадерами. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2017, 15:48 |
|
||
|
ClassCastException кастомизации класслоадинга
|
|||
|---|---|---|---|
|
#18+
questionerТак я то же самое и написал. разве нет? Я уже перестаю удивлятся тому что на каждый ответ вы комментируете что вы уже в курсе. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2017, 15:56 |
|
||
|
ClassCastException кастомизации класслоадинга
|
|||
|---|---|---|---|
|
#18+
BlazkowiczquestionerТак я то же самое и написал. разве нет? Я уже перестаю удивлятся тому что на каждый ответ вы комментируете что вы уже в курсе. не обижайтесь. У меня нет цели показать, что мол я и так всё знаю. Знал бы - сюда не написал бы. Но на мой взгляд я написал то же, что и Вы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2017, 16:27 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=39383249&tid=2123271]: |
0ms |
get settings: |
6ms |
get forum list: |
11ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
53ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
50ms |
get tp. blocked users: |
1ms |
| others: | 208ms |
| total: | 347ms |

| 0 / 0 |
