Ricardo Ferreira
Ricardo Ferreira

Reputation: 41

How to solve NoClassDefFoundError on Heroku using maven?

I am trying to deploy my app on heroku and i am getting a NoClassDefFoundError while calling the index.html page. The Error log looks like this:

    2018-11-04T19:13:02.080531+00:00 heroku[web.1]: Starting process with 
    command `java $JAVA_OPTS -cp target/classes:target/dependency/* 
    com.treslines.server.Server`

    2018-11-04T19:13:05.913978+00:00 app[web.1]: Setting 
    JAVA_TOOL_OPTIONS defaults based on dyno size. Custom settings will 
    override them.

    2018-11-04T19:13:05.926232+00:00 app[web.1]: Picked up 
    JAVA_TOOL_OPTIONS: -Xmx300m -Xss512k -XX:CICompilerCount=2 
    -Dfile.encoding=UTF-8

    2018-11-04T19:13:06.250733+00:00 app[web.1]: Error: A JNI error has 
    occurred, please check your installation and try again

    2018-11-04T19:13:06.250788+00:00 app[web.1]: Exception in thread 
    "main" java.lang.NoClassDefFoundError: com/j256/ormlite/support
    /ConnectionSource

    2018-11-04T19:13:06.250796+00:00 app[web.1]: at 
    java.lang.Class.getDeclaredMethods0(Native Method)

    2018-11-04T19:13:06.250799+00:00 app[web.1]: at 
    java.lang.Class.privateGetDeclaredMethods(Class.java:2701)

    2018-11-04T19:13:06.250801+00:00 app[web.1]: at 
    java.lang.Class.privateGetMethodRecursive(Class.java:3048)

    2018-11-04T19:13:06.250808+00:00 app[web.1]: at 
    java.lang.Class.getMethod0(Class.java:3018)

    2018-11-04T19:13:06.250810+00:00 app[web.1]: at 
    java.lang.Class.getMethod(Class.java:1784)

    2018-11-04T19:13:06.250812+00:00 app[web.1]: at ... 7 more

So I understand the error and i looked up in my target/dependency folder locally and there are all dependencies of the missing class inside of ormlite-core-5.1 and ormlite-jdbc-5.1 libraries.

enter image description here

So far so good. My proc file on heroku looks like this:

    web: java $JAVA_OPTS -cp target/classes:target/dependency/* com.treslines.server.Server

In my maven pom.xml, i have those configurations:

...

    <dependency>
        <groupId>com.j256.ormlite</groupId>
        <artifactId>ormlite-core</artifactId>
        <version>5.1</version>
    </dependency>

    <dependency>
        <groupId>com.j256.ormlite</groupId>
        <artifactId>ormlite-jdbc</artifactId>
        <version>5.1</version>
    </dependency>

...

    <configuration>
                <descriptorRefs>
                    <!-- This tells Maven to include all dependencies -->
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <archive>
                    <manifest>
                        <mainClass>com.treslines.server.Server</mainClass>
                    </manifest>
                </archive>
            </configuration>

...

    <plugin>
            <groupId>com.heroku.sdk</groupId>
            <artifactId>heroku-maven-plugin</artifactId>
            <version>0.4.4</version>
            <configuration>
                <jdkVersion>1.8</jdkVersion>
                <!-- Use your own application name >>> heroku enforces lowcase names -->
                <appName>stocknews</appName>
                <processTypes>
                    <!-- Tell Heroku how to launch your application -->
                    <web>java $JAVA_OPTS -cp target/classes:target/dependency/* com.treslines.server.Server</web>
                </processTypes>
            </configuration>
        </plugin>

The code runs locally on localhost like a charm. I pushed the code to heroku successfully, everything runs just fine, maven build success and so on. But when i call heroku open on the command cli or type the url on the browser, the NoClassDefFoundError occurs.

Does anyone have an idea how to solve it? Is there a way to access the deployed code on heroku to see what was deployed effectivelly?

Upvotes: 2

Views: 1409

Answers (2)

Ricardo Ferreira
Ricardo Ferreira

Reputation: 41

RESOLVED

Resolution: Both tutorials on spark java and on heroku are outdated. The websites said you should have a processType like this:

...

    <web>java $JAVA_OPTS -cp target/classes:target/dependency/* com.treslines.server.Server</web>

...

However, while deploying it on Heroku, the maven-assembly-plugin i had, didn't create the target/dependecy folder as used to. To solve this problem, you must include the missing dependencies like this:

          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>3.1.1</version>
            <executions>
              <execution>
                <id>copy-dependencies</id>
                <phase>package</phase>
                <goals>
                  <goal>copy-dependencies</goal>
                </goals>
                <configuration>
                  <outputDirectory>target/dependency/</outputDirectory>
                  <overWriteReleases>false</overWriteReleases>
                  <overWriteSnapshots>false</overWriteSnapshots>
                  <overWriteIfNewer>true</overWriteIfNewer>
                </configuration>
              </execution>
            </executions>
          </plugin>

when you deploy your app on heroku, there is also a command line to see and inspect the deployed artefacts. heroku run bash After that you can type ls to see if your deployed package is correct.

Than you just have to push it to your heroku master by typing: git push heroku master Maven will re-deploy it, but that time it will append all project dependencies to the folder target/dependency as expected. Now you can call heroku open to browse your app.

Upvotes: 1

codefinger
codefinger

Reputation: 10338

Begin by updating the heroku-maven-plugin. You're on 0.4.4, but the latest is 2.0.6:

<version>2.0.6</version>

Upvotes: 1

Related Questions