在tomcat 8中,Web应用程序依赖项(/ WEB-INF / lib)是否为提供的依赖项提供范围?

时间:2017-08-14 00:51:41

标签: java tomcat classloader dependency-management tomcat8

我尝试在我的网络应用程序中安装hbase / hadoop驱动程序为provided

此过程在Websphere中使用"共享库"引用,所以这似乎是特定于tomcat的。 Tomcat 8.0.x和8.5.x,Java 8.

来自pom.xml

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>org.apache.hbase</groupId>
        <artifactId>hbase-common</artifactId>
        <version>1.1.2</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-common</artifactId>
        <version>2.7.1</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>14.0.1</version>
    </dependency>

一个类在静态初始值设定项中初始化hbase对象:

public class SimpleServlet extends HttpServlet {

static {
    ClassLoader classLoader = SimpleServlet.class.getClassLoader();
    URL[] urLs = ((URLClassLoader) classLoader).getURLs();
    LOGGER.info("SimpleServlet.class: " + Arrays.asList(urLs));
    while(classLoader.getParent() != null) {
        classLoader = classLoader.getParent();
        urLs = ((URLClassLoader) classLoader).getURLs();
        LOGGER.info("parent: " + Arrays.asList(urLs));
    }

    classLoader = Thread.currentThread().getContextClassLoader();
    urLs = ((URLClassLoader) classLoader).getURLs();
    LOGGER.info("context: " + Arrays.asList(urLs));
    while(classLoader.getParent() != null) {
        classLoader = classLoader.getParent();
        urLs = ((URLClassLoader) classLoader).getURLs();
        LOGGER.info("parent: " + Arrays.asList(urLs));
    }
}

    private static Configuration hbaseConfig = HBaseConfiguration.create();
    ...
}

我提供的代码已安装在the usual way

$ ls -l ../tomcat/8.5.8/libexec/lib/
...
-rw-r--r--   1 ...  3429485 Aug 13 14:54 hadoop-common-2.7.1.jar
-rw-r--r--   1 ...   530078 Aug 13 14:55 hbase-common-1.1.2.jar
-rw-r--r--   1 ...    61829 Aug 13 14:56 commons-logging-1.2.jar

战争看起来像预期的那样:

$ jar tf .../target/sandbox-1.0-SNAPSHOT.war
META-INF/
META-INF/MANIFEST.MF
WEB-INF/
WEB-INF/classes/
WEB-INF/classes/com/
WEB-INF/classes/com/example/
WEB-INF/classes/webapp/
WEB-INF/classes/webapp/WEB-INF/
WEB-INF/lib/
WEB-INF/classes/com/example/SimpleServlet.class
WEB-INF/lib/guava-14.0.1.jar  // <-- here it is
WEB-INF/web.xml
...

hbase静态方法在内部的某个构造函数中使用guava,并且Web应用程序在部署时失败:

13-Aug-2017 20:19:37.680 SEVERE [RMI TCP Connection(2)-127.0.0.1] org.apache.catalina.core.StandardContext.loadOnStartup Servlet [simpleServlet] in web application [] threw load() exception
 java.lang.ClassNotFoundException: com.google.common.base.Preconditions
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at org.apache.hadoop.conf.Configuration$DeprecationDelta.<init>(Configuration.java:328)
    at org.apache.hadoop.conf.Configuration$DeprecationDelta.<init>(Configuration.java:341)
    at org.apache.hadoop.conf.Configuration.<clinit>(Configuration.java:423)
    at com.example.SimpleServlet.<clinit>(SimpleServlet.java:20)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at java.lang.Class.newInstance(Class.java:442)
    at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:119)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1050)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:989)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4913)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5223)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:752)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:728)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
    at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1702)
    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 org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:482)
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:431)
    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 org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
    at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468)
    at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76)
    at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309)
    at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1401)
    at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829)
    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 sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:324)
    at sun.rmi.transport.Transport$1.run(Transport.java:200)
    at sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

如果将guava添加到共享libs目录,则提供的依赖项会看到它。

guava位于静态方法之前的静态初始化程序中的类路径输出上,共享库在父项中可见,如预期的那样:

[RMI TCP Connection(2)-127.0.0.1] INFO com.example.SimpleServlet - SimpleServlet.class: [file:.../webapps/ROOT/WEB-INF/classes/, file:.../webapps/ROOT/WEB-INF/lib/guava-14.0.1.jar, ...]
[RMI TCP Connection(2)-127.0.0.1] INFO com.example.SimpleServlet - parent: [..., .../lib/commons-logging-1.2.jar, .../lib/hadoop-common-2.7.1.jar, .../lib/hbase-common-1.1.2.jar, ...], ...
[RMI TCP Connection(2)-127.0.0.1] INFO com.example.SimpleServlet - context: [file:.../webapps/ROOT/WEB-INF/classes/, file:.../webapps/ROOT/WEB-INF/lib/guava-14.0.1.jar, ...]
[RMI TCP Connection(2)-127.0.0.1] INFO com.example.SimpleServlet - parent: [..., .../lib/commons-logging-1.2.jar, .../lib/hadoop-common-2.7.1.jar, .../lib/hbase-common-1.1.2.jar, ...], ...

为什么guava对提供的依赖项不可见?

0 个答案:

没有答案