Я хочу создать экземпляр и отобразить все классы в моем классе для определенного типа.
Я выполнил сканирование с помощью библиотеки Reflections
и получил список загруженных классов.
Затем, когда я их сопоставляю, я проверяю конфликты (ключ - это простое имя класса).
Когда это произойдет, я хотел бы сделать исключение, указав полное имя конфликтующих классов, а также путь, из которого они были загружены (например, в которых JARs
можно найти каждый).
Я понимаю, что можно загрузить класс из памяти, но, предполагая, что я загружал его из JAR
на диске, мне интересно, есть ли способ получить этот путь...
См. Фрагмент кода ниже:
if (isConflictingFactoryRegistered(key, myFactory)) {
Class<? extends MyFactory> class1 = factoryMap.get(key).getClass();
Class<? extends MyFactory> class2 = myFactory.getClass();
try {
throw new RuntimeException("Found two conflicting factories for " + key
+ ": 1. " + class1 + " in " + getClass().getResource(class1.getSimpleName()+".class").toURI() +
" 2. " + class2 + " in " + getClass().getResource(class2.getSimpleName()+".class").toURI());
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
} else {
factoryMap.put(myFactory.getName(), myFactory);
}
Этот код компилируется - но это не сработает; getClass(). getResource (class1.getSimpleName() + ". class") возвращает null. Как я могу получить путь к .class
?
Я предлагаю вам заменить
throw new RuntimeException("Found two conflicting factories for " + key
+ ": 1. " + class1 + " in " + getClass().getResource(class1.getSimpleName()+".class").toURI() +
" 2. " + class2 + " in " + getClass().getResource(class2.getSimpleName()+".class").toURI());
с
throw new RuntimeException("Found two conflicting factories for " + key
+ ": 1. " + class1 + " in " + class1.getResource(class1.getSimpleName()+".class").toURI() +
" 2. " + class2 + " in " + class2.getResource(class2.getSimpleName()+".class").toURI());
Это работает для двух произвольных классов на моей машине.
В общем, я думаю, что Class.getResource()
может находить ресурсы только для того же ClassLoader, которые загружали этот конкретный класс - в соответствии с API,
Этот метод делегирует этот загрузчик класса объекта. Если этот объект был загружен загрузчиком класса bootstrap, этот метод делегирует ClassLoader.getSystemResource(java.lang.String).
Я подозреваю, что если вы посмотрите на getClass().getClassLoader()
и class1.getClassLoader()
в вашем примере, вы можете обнаружить, что они разные.