在tomcat根目录中的Web应用程序中找不到TransformerFactory

时间:2015-01-28 14:12:13

标签: java tomcat classloader

我创建了一个使用Saxon库进行XSLT转换的Web应用程序。 当Web应用程序使用自己的名称(等于webapps目录中子目录的名称)部署在Tomcat上时,此应用程序很有效。 但是现在我已经将server.xml更改为使用此Web应用程序作为根应用程序,现在它无法加载Saxon库。

我认为这与类加载器有关。我使用类加载器来查找配置文件,当我将此应用程序设置为tomcat根应用程序时,这些文件也崩溃了。我能够使用ServletContext加载配置文件,以便解决问题。

但现在我收到以下错误:

Caused by: javax.xml.transform.TransformerFactoryConfigurationError: Provider net.sf.saxon.TransformerFactoryImpl not found

使用:

调用
TransformerFactory tf = TransformerFactory.newInstance("net.sf.saxon.TransformerFactoryImpl",null);

我对server.xml所做的更改(我添加了<Context>元素):

  <Host name="localhost"  appBase="webapps"
        unpackWARs="true" autoDeploy="true">

    <!-- SingleSignOn valve, share authentication between web applications
         Documentation at: /docs/config/valve.html -->
    <!--
    <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
    -->

    <!-- Access log processes all example.
         Documentation at: /docs/config/valve.html
         Note: The pattern used is equivalent to using pattern="common" -->
    <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
           prefix="localhost_access_log." suffix=".txt"
           pattern="%h %l %u %t &quot;%r&quot; %s %b" />
    <Context docBase="foodvoc-pipelines" path="/" reloadable="true"/> 
  </Host>

当使用TransformerFactory方法中的类名创建newInstance时,tomcat似乎找不到SAXON库。

我可以通过编程方式将目录(Web应用程序中的lib目录)添加到类路径中吗?或者我应该将SAXON库添加到tomcat在其类路径中使用的另一个目录(哪个?)?我可以直接创建撒克逊TransformerFactory(没有类加载器)吗?或者我的配置是否使该应用程序成为根应用程序错误?

1 个答案:

答案 0 :(得分:0)

我能够通过将tomcat webapp中的lib目录以编程方式添加到类加载器中来实现这一目的。

说实话,我对这个解决方案并不满意,但它有效......

必须按照answer to this question中的描述静态添加路径。这是我的FoodVocApplication类中的静态方法。

private static void addPath(File file) throws NoSuchMethodException, MalformedURLException, InvocationTargetException, IllegalAccessException {
    URI u = file.toURI();
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    Class<URLClassLoader> urlclass = URLClassLoader.class;
    Method method = urlclass.getDeclaredMethod("addURL", new Class[]{URL.class});
    method.setAccessible(true);
    method.invoke(classLoader, new Object[]{u.toURL()});
}

然后可以在初始化期间通过以下方式调用此方法:

FoodVocApplication.addPath(new File(webInff, "lib"));

其中webInff是指向webapp中WEB-INF目录的File对象。