Eclipse XML Parser "Поставщики" конфликтуют с rt.jar
Обратите внимание: хотя есть несколько вопросов по SO, которые вставляются в похожее исключение и трассировку стека, этот вопрос определенно не является обманом ни одного из них, так как я пытаюсь понять, где происходит неправильная загрузка классов.
Привет, Java 8/Groovy 2.4.3/Eclipse Luna здесь. Я использую Java-клиент BigIP iControl (для программного управления мощным балансировщиком нагрузки), который в свою очередь использует Apache Axis 1.4. При использовании Axis 1.4 я получаю следующую трассировку стека (из консоли Eclipse):
Caught: javax.xml.parsers.FactoryConfigurationError: Provider for javax.xml.parsers.DocumentBuilderFactory cannot be found
javax.xml.parsers.FactoryConfigurationError: Provider for javax.xml.parsers.DocumentBuilderFactory cannot be found
at org.apache.axis.utils.XMLUtils.getDOMFactory(XMLUtils.java:221)
at org.apache.axis.utils.XMLUtils.<clinit>(XMLUtils.java:83)
at org.apache.axis.configuration.FileProvider.configureEngine(FileProvider.java:179)
at org.apache.axis.AxisEngine.init(AxisEngine.java:172)
at org.apache.axis.AxisEngine.<init>(AxisEngine.java:156)
at org.apache.axis.client.AxisClient.<init>(AxisClient.java:52)
at org.apache.axis.client.Service.getAxisClient(Service.java:104)
at org.apache.axis.client.Service.<init>(Service.java:113)
at iControl.LocalLBPoolLocator.<init>(LocalLBPoolLocator.java:21)
at iControl.Interfaces.getLocalLBPool(Interfaces.java:351)
at com.me.myapp.F5Client.run(F5Client.groovy:27)
Хммм, давайте посмотрим на это XMLUtils.getDOMFactory
метод:
private static DocumentBuilderFactory getDOMFactory() {
DocumentBuilderFactory dbf;
try {
dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
}
catch( Exception e ) {
log.error(Messages.getMessage("exception00"), e );
dbf = null;
}
return( dbf );
}
ОК, LN 221, это вызов DocumentBuilderFactory.newInstance()
Итак, давайте посмотрим на это:
public static DocumentBuilderFactory newInstance() {
return FactoryFinder.find(
/* The default property name according to the JAXP spec */
DocumentBuilderFactory.class, // "javax.xml.parsers.DocumentBuilderFactory"
/* The fallback implementation class name */
"com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
}
Сюжет сгущается! Теперь давайте взглянем на FactoryFinder.find
:
static <T> T find(Class<T> type, String fallbackClassName)
throws FactoryConfigurationError
{
final String factoryId = type.getName();
dPrint("find factoryId =" + factoryId);
// lots of nasty cruft omitted for brevity...
// Try Jar Service Provider Mechanism
T provider = findServiceProvider(type);
if (provider != null) {
return provider;
}
if (fallbackClassName == null) {
throw new FactoryConfigurationError(
"Provider for " + factoryId + " cannot be found"); // <<-- Ahh, here we go
}
dPrint("loaded from fallback value: " + fallbackClassName);
return newInstance(type, fallbackClassName, null, true);
}
Так что, если я правильно понимаю, это бросает FactoryConfigurationError
потому что он не может найти основной "класс провайдера" (что бы это ни значило) и не был указан запасной вариант. Но не так ли?!? Призыв к FactoryFinder.find
включен ненулевой "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl"
строковый аргумент. Это вызывает у меня подозрение, что с моим классным путем что-то действительно шаткое, и что у меня есть мошенник DocumentBuilderFactory
(не тот, который определен в rt.jar/javax/xml/parsers
) где-то в моем коде, который передает NULL-аргумент этому методу поиска.
Но это также не имеет смысла, потому что Axis 1.4 не имеет (по крайней мере, согласно репозиторию Maven) каких-либо зависимостей... что означает единственный "поставщик" для javax.xml.*
будет rt.jar
, Если, возможно, "Затмение" как-то портит? Я так растерялся, помогите пожалуйста:-/
Обновить
Это определенно проблема Eclipse. Если я упаковываю свое приложение как исполняемый файл JAR и запускаю его из командной строки, я не получаю этого исключения.