提问者:小点点

为部署到heroku tomcat Java Web WAR未找到添加依赖项的类


在这里遵循本教程: https://devcenter.heroku.com/articles/java-webapp-runner ,我更改了POM以包含几个依赖项和我的Web应用程序的源代码(servlet),以利用init()方法中添加的依赖项来加载文件。我使用webapp-runmvn heroku: run-war在本地测试了该应用程序,并且servlet按预期工作!但是,当我使用mvn heroku:devy-war部署到Heroku,并且在完成部署后导航到链接时,我在第一次打开链接时收到以下错误:

HTTP Status 500 - Servlet.init() for servlet HelloWorld threw exception

type Exception report

message Servlet.init() for servlet HelloWorld threw exception

description The server encountered an internal error that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: Servlet.init() for servlet HelloWorld threw exception
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674)
    org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
    org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    java.lang.Thread.run(Thread.java:745)

root cause

java.lang.ExceptionInInitializerError
    org.nd4j.nativeblas.NativeOpsHolder.<init>(NativeOpsHolder.java:16)
    org.nd4j.nativeblas.NativeOpsHolder.<clinit>(NativeOpsHolder.java:9)
    org.nd4j.linalg.cpu.nativecpu.ops.NativeOpExecutioner.<init>(NativeOpExecutioner.java:37)
    sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    java.lang.Class.newInstance(Class.java:442)
    org.nd4j.linalg.factory.Nd4j.initWithBackend(Nd4j.java:5267)
    org.nd4j.linalg.factory.Nd4j.initContext(Nd4j.java:5183)
    org.nd4j.linalg.factory.Nd4j.<clinit>(Nd4j.java:167)
    org.deeplearning4j.models.embeddings.loader.WordVectorSerializer.loadTxt(WordVectorSerializer.java:1578)
    org.deeplearning4j.models.embeddings.loader.WordVectorSerializer.loadTxtVectors(WordVectorSerializer.java:1502)
    herokutest.HelloWorld.init(HelloWorld.java:41)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674)
    org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
    org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    java.lang.Thread.run(Thread.java:745)

root cause

java.lang.RuntimeException: ND4J is probably missing dependencies. For more information, please refer to: http://nd4j.org/getstarted.html
    org.nd4j.nativeblas.NativeOps.<clinit>(NativeOps.java:39)
    org.nd4j.nativeblas.NativeOpsHolder.<init>(NativeOpsHolder.java:16)
    org.nd4j.nativeblas.NativeOpsHolder.<clinit>(NativeOpsHolder.java:9)
    org.nd4j.linalg.cpu.nativecpu.ops.NativeOpExecutioner.<init>(NativeOpExecutioner.java:37)
    sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    java.lang.Class.newInstance(Class.java:442)
    org.nd4j.linalg.factory.Nd4j.initWithBackend(Nd4j.java:5267)
    org.nd4j.linalg.factory.Nd4j.initContext(Nd4j.java:5183)
    org.nd4j.linalg.factory.Nd4j.<clinit>(Nd4j.java:167)
    org.deeplearning4j.models.embeddings.loader.WordVectorSerializer.loadTxt(WordVectorSerializer.java:1578)
    org.deeplearning4j.models.embeddings.loader.WordVectorSerializer.loadTxtVectors(WordVectorSerializer.java:1502)
    herokutest.HelloWorld.init(HelloWorld.java:41)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674)
    org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
    org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    java.lang.Thread.run(Thread.java:745)

root cause

java.lang.UnsatisfiedLinkError: no jnind4j in java.library.path
    java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
    java.lang.Runtime.loadLibrary0(Runtime.java:870)
    java.lang.System.loadLibrary(System.java:1122)
    org.bytedeco.javacpp.Loader.loadLibrary(Loader.java:727)
    org.bytedeco.javacpp.Loader.load(Loader.java:502)
    org.nd4j.nativeblas.NativeOps.<clinit>(NativeOps.java:37)
    org.nd4j.nativeblas.NativeOpsHolder.<init>(NativeOpsHolder.java:16)
    org.nd4j.nativeblas.NativeOpsHolder.<clinit>(NativeOpsHolder.java:9)
    org.nd4j.linalg.cpu.nativecpu.ops.NativeOpExecutioner.<init>(NativeOpExecutioner.java:37)
    sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    java.lang.Class.newInstance(Class.java:442)
    org.nd4j.linalg.factory.Nd4j.initWithBackend(Nd4j.java:5267)
    org.nd4j.linalg.factory.Nd4j.initContext(Nd4j.java:5183)
    org.nd4j.linalg.factory.Nd4j.<clinit>(Nd4j.java:167)
    org.deeplearning4j.models.embeddings.loader.WordVectorSerializer.loadTxt(WordVectorSerializer.java:1578)
    org.deeplearning4j.models.embeddings.loader.WordVectorSerializer.loadTxtVectors(WordVectorSerializer.java:1502)
    herokutest.HelloWorld.init(HelloWorld.java:41)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674)
    org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
    org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    java.lang.Thread.run(Thread.java:745)

root cause

java.lang.UnsatisfiedLinkError: no nd4j in java.library.path
    java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
    java.lang.Runtime.loadLibrary0(Runtime.java:870)
    java.lang.System.loadLibrary(System.java:1122)
    org.bytedeco.javacpp.Loader.loadLibrary(Loader.java:727)
    org.bytedeco.javacpp.Loader.load(Loader.java:493)
    org.nd4j.nativeblas.NativeOps.<clinit>(NativeOps.java:37)
    org.nd4j.nativeblas.NativeOpsHolder.<init>(NativeOpsHolder.java:16)
    org.nd4j.nativeblas.NativeOpsHolder.<clinit>(NativeOpsHolder.java:9)
    org.nd4j.linalg.cpu.nativecpu.ops.NativeOpExecutioner.<init>(NativeOpExecutioner.java:37)
    sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    java.lang.Class.newInstance(Class.java:442)
    org.nd4j.linalg.factory.Nd4j.initWithBackend(Nd4j.java:5267)
    org.nd4j.linalg.factory.Nd4j.initContext(Nd4j.java:5183)
    org.nd4j.linalg.factory.Nd4j.<clinit>(Nd4j.java:167)
    org.deeplearning4j.models.embeddings.loader.WordVectorSerializer.loadTxt(WordVectorSerializer.java:1578)
    org.deeplearning4j.models.embeddings.loader.WordVectorSerializer.loadTxtVectors(WordVectorSerializer.java:1502)
    herokutest.HelloWorld.init(HelloWorld.java:41)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674)
    org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
    org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    java.lang.Thread.run(Thread.java:745)

程序文件

web:    java $JAVA_OPTS -jar target/dependency/webapp-runner.jar --port $PORT target/*.war

POM.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.tomcat.heroku</groupId>
  <artifactId>heroku-tomcat</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>heroku-tomcat Maven Webapp</name>
  <url>http://maven.apache.org</url>


  <properties>
    <nd4j.version>0.6.0</nd4j.version>
    <dl4j.version>0.6.0</dl4j.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>


  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.deeplearning4j</groupId>
      <artifactId>deeplearning4j-ui</artifactId>
      <version>${dl4j.version}</version>
    </dependency>

    <dependency>
      <groupId>org.deeplearning4j</groupId>
      <artifactId>deeplearning4j-nlp</artifactId>
      <version>${dl4j.version}</version>
    </dependency>
    <dependency>
      <groupId>org.nd4j</groupId>
      <artifactId>nd4j-native</artifactId>
      <version>${nd4j.version}</version>
    </dependency>
    <dependency>
      <groupId>org.nd4j</groupId>
      <artifactId>nd4j-common</artifactId>
      <version>${nd4j.version}</version>
    </dependency>

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>



  </dependencies>


  <build>
    <finalName>heroku-tomcat</finalName>
    <plugins>

        <plugin>
          <groupId>com.heroku.sdk</groupId>
          <artifactId>heroku-maven-plugin</artifactId>
          <version>1.1.1</version>
        </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>2.3</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals><goal>copy</goal></goals>
            <configuration>
              <artifactItems>
                <artifactItem>
                  <groupId>com.github.jsimone</groupId>
                  <artifactId>webapp-runner</artifactId>
                  <version>8.0.30.2</version>
                  <destFileName>webapp-runner.jar</destFileName>
                </artifactItem>
              </artifactItems>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>


</project>

源代码:

package herokutest;

import org.apache.commons.lang.math.NumberUtils;
import org.bytedeco.javacpp.presets.opencv_core;
import org.deeplearning4j.models.embeddings.loader.WordVectorSerializer;
import org.deeplearning4j.models.embeddings.wordvectors.WordVectors;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.Collection;

/**
 * Created by Mr_RexZ on 10/23/2016.
 */
public class HelloWorld extends HttpServlet {

    private String message;
    String loc="/WEB-INF/glove.6B.50d.txt";


    @javax.ws.rs.core.Context
    ServletContext context;
    WordVectors wordVectors;

    public void init(final ServletConfig config) throws ServletException
    {
        message = "Hi";

        String fullPath = config.getServletContext().getRealPath(loc);
        File file = new File(fullPath);
        try {
            wordVectors = WordVectorSerializer.loadTxtVectors(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    public void doGet(HttpServletRequest request,
                      HttpServletResponse response)
            throws ServletException, IOException
    {

        response.setContentType("text/html");

        boolean submitSim = request.getParameter("submitSim") != null;
        boolean submitAn = request.getParameter("submitAn") != null;


        String findSim = request.getParameter("findSim");
        request.setAttribute("findSim", findSim);

        String resSim = request.getParameter("resSim");
        request.setAttribute("resSim", resSim);
        if (request.getParameter("numSim")!=null && NumberUtils.isNumber(request.getParameter("numSim"))) {
            int numSim = Integer.parseInt(request.getParameter("numSim"));
            request.setAttribute("numSim", request.getParameter("numSim"));

        if(submitSim) {
            Collection<String> lst = wordVectors.wordsNearest(findSim, numSim);
            request.setAttribute("resSim", Arrays.toString(lst.toArray()));
        }

        }
        String an1 = request.getParameter("an1");
        String an2 = request.getParameter("an2");
        String an3 = request.getParameter("an3");
        request.setAttribute("an1", an1);
        request.setAttribute("an2", an2);
        request.setAttribute("an3", an3);

        String resAn = request.getParameter("resAn");
        request.setAttribute("resAn", resAn);

        if (request.getParameter("numAn")!=null && NumberUtils.isNumber(request.getParameter("numAn"))) {
            int numAn = Integer.parseInt(request.getParameter("numAn"));
            request.setAttribute("numAn", request.getParameter("numAn"));

        if (submitAn) {
            Collection<String> lst =  wordVectors.wordsNearest(Arrays.asList(new String[] {an2,an3}) , Arrays.asList(new String[] {an1}),numAn);
            request.setAttribute("resAn", Arrays.toString(lst.toArray()));
        }
        }
        request.getRequestDispatcher("/index.jsp").forward(request, response);
    }


    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    public void destroy()
    {
        // do nothing.
    }
}

但是,当我删除其他依赖项时,Web 应用程序可以正常工作。据我了解,使用 web-app runner 在本地测试应用程序以测试应用程序是否可以正常工作就足以查看它在部署到 Heroku 时是否也能正常工作,因为它可以防止运行时问题。但我不明白为什么它在增加依赖性的情况下不起作用?


共1个答案

匿名用户

您的根本问题实际上与nd4j中的c代码有关。我假设你已经有了一个经过训练的模型,这意味着你应该相对熟悉nd4j后端(http://nd4j.org/backend.html). 如果是这种情况,请确保将具有最新版本nd4j的nd4j本地平台添加到类路径中。

Nd4j原生平台将各种平台的所有原生库捆绑在一起。

如果由于任何原因这不起作用,您可以采用分类器路线。

阅读以下内容:maven中Classifier标签的用途是什么?

您将在此处看到:http://repo1.maven.org/maven2/org/nd4j/nd4j-native/0.6.0/

查看jar文件的名称,您将在此处看到nd4j-native-SOME CLASSIFIER

由于您是在linux上部署的,您可能需要:linux-x86_64.jar

这是操作系统CHIP_ARCHITECTURE在那里,你还将看到Mac,Windows,powerpc和android。

现在的数值是0.6

dl4j 示例将始终具有最新版本:github.com/deeplearning4j/dl4j-examples