Heroku can't find or load main class - java

I have a problem with heroku. I defined my Procfile and my pom.xml file as it was said in guide. But when I'm trying to launch my app after deploy on heroku or localy (command: sh target/bin/OPCBot).
I recieve an error Error: Could not find or load main class com.eiei.odessaportcheck.OdessaPortCheckApplication.
How can I fix this?
This is my Procfile content:
worker: sh target/bin/OPCBot
And here is my code from pom.xml:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.1.1</version>
<configuration>
<assembleDirectory>target</assembleDirectory>
<programs>
<program>
<mainClass>com.eiei.odessaportcheck.OdessaPortCheckApplication</mainClass>
<name>OPCBot</name>
</program>
</programs>
</configuration>
<executions>
<execution>
<phase>package</phase><goals><goal>assemble</goal></goals>
</execution>
</executions>
</plugin>
P.S. I thik that problem lies in .bat file generated by appassembler-maven-plugin for heroku. When I try to launch it separately it says it can't find my main class.
I aslo tried:
<program>
<mainClass>OdessaPortCheckApplication</mainClass>
<name>OPCBot</name>
</program>

The problem was that I messed up with a heroku tutorial. I should have used a tutorial for spring application instead of the regular one. After I have launched a project without spring, all was ok.

Related

ClassNotFoundEcception when running jar through Terminal (or command prompt)

So I know there are tons of questions like this one, and I have been through all of them, but I can't seem to find one like mine.
Basically, I have a java project with a lot of Maven Dependencies. The project compiles and runs just fine when I run it with IntelliJ, but now I am trying to run it through the terminal (or command prompt). In order to do that, I ran mvn package so I can get a jar file and when I run java -jar server.jar, I get the classic ClassNotFoundEcception exception. In my case, it says that it is:
Caused by: java.lang.ClassNotFoundException: org.apache.commons.fileupload.FileItemFactory
and when I suppress it by (temporarily) commenting out the part of the code that uses this class, I end up with the same error for another class. At this point, I know that I need to have some sort of folder (correct me if I'm wrong, but I believe it is called CLASSPATH) which contains the .jar of each dependency. Can anyone explain to me the situation in a clear way and how am I supposed to organize the .jar file of each dependency (if that is even what I have to do to fix my error).
The org.apache.commons.fileupload.FileItemFactory and most likely other dependencies are not in the classpath. Intellij includes dependencies in the classpath automatically, and this is the reason it works.
To run the program from CMD with all your depedecies included define the following plugin in pom.xml:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
and run:
mvn clean package
java -jar server-jar-with-dependencies.jar

Error when running docker container "NoClassDefFoundError"

I am trying to dockerize a simple Spring Boot Application, built with Maven.
Dockerfile:
FROM openjdk:latest
COPY target/backend-1.0-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-jar","app.jar"]
When I run the .jar without the container (java -jar target/backend-1.0-SNAPSHOT.jar), everything works fine and the app is running.
Now I create the container with docker build -t company/backend .
But when I try to run the docker container with docker run -p 8080:8080 company/backend the following error occurs:
Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/boot/SpringApplication
at de.company.backend.Application.main(Application.java:10)
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.SpringApplication
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
... 1 more
It seems like docker does not find the main class, even though it is defined in my pom.xml:
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<mainClass>de.elbdev.backend.Application</mainClass>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>${mainClass}</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
Main Class:
package de.company.backend;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
In your pom.xml, the copy-dependencies goal is specified at the install phase : too late the package of the jar was already done.
I am trying to dockerize a simple Spring Boot Application, built with
Maven.
You don't need to declare any plugin to create a fat jar with spring boot that could be run by a docker container.
Declaring these plugins is error prone (and should be used only in corner cases) while the repackage goal of the spring boot maven plugin attached by default to the package phase of maven will create for you the fat jar :
Repackages existing JAR and WAR archives so that they can be executed
from the command line using java -jar
Juste remove these plugins declarations and execute mvn clean package and it should be good.
Side note :
FROM openjdk:latest
Don't use latest as image version but favor a specific version of the image othewhise you could have bad surprises. As you use JDK 8, you could specify a JRE or a JDK 8 such as : FROM openjdk:8-jre-alpine.
I had the same problem as you.
you need to add plugin in your pom.xml.
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
If you input as above, it works normally.
and check MANIFEST.MF (in .jar file)
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: {your main class}

Use Maven Replace Plugin to replace a phrase on a generated Java file inside Target/generated-sources

I spent hours on this problem, searching several Google and SO entries, I have some ideas but not getting the result.
I have a maven file that does something like this:
grab a jar containing JSON schemas, and unpack them.
Using the Maven Replacer plugin (v 1.5.3), replace a line in a schema file called “MySchema.json” as such:
”Hello” :
”HelloWorld” :
then Maven would use another plugin to compile a class called “converter.java” and runs this class to output a Java file based on “MySchema.json”. let’s call the generated Java file “MyPojo.java”.
Now, I want Maven to replace a line in “MyPojo.java”, but no matter what I do I cannot achieve this.
I tried:
include a separate replace plugin entry for step 4 after the plugin that converts schemas to Java, but ofcourse this caused Maven to complain about existing replace plugin with same artifact/group id from step 2.
Tried adding a separate execution id to the goal “replace” for second plugin, this is invalid for this plugin.
There is a parent project to my current project folder, I tried putting another replacer plugin in the parent POM and make the phase to be any of the “package”, “generate-resources”, “compile”, etc. did not work. Note: the phase for replacements inside “MySchema.json” (in my current project POM) is generate-sources.
give absolute path to the Java, it kept complaining that path does not exist. But I copied and pasted the path to the Java inside windows explorer address bar after it was generated and could read it from Windows explorer. Note that the generated Java file “MyPojo.java”, went under “target/generated-sources” which is sourced by a parent POM above this project using a Maven Helper plugin in parent POM, so this folder should be visible as a source for further compilation. That Maven Helper plugin has phase generate-sources.
Use with same result as above
In my current project (non-parent one) this is the POM code:
<build>
<!—execute a plugin grab schemas jar and unpack schemas-->
...
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.3</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<include>${project.basedir}/target/schemas/MySchema.json</include>
</includes>
<replacements>
<replacement>
<token>"Hello":</token>
<value>"Hello World":</value>
</replacement>
</replacements>
</configuration>
</plugin>
<!-- execute a Plugin for converting shcemas to POJO -->
. . .
</plugins>
</build>
</project>
You should be able to declare the plugin only once and run two replace execution at different Maven Build Lifecycle phases:
Before the Json -> POJO conversion
After the Json -> POJO conversion
So, translating that into could would result in something like:
<plugin>
<!-- (unique) plugin declaration -->
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>maven-replacer-plugin</artifactId>
<version>1.3.5</version>
<executions>
<!-- first execution: replace on json file -->
<execution>
<id>replace-for-json</id>
<phase>some-phase-before-conversion</phase>
<goals>
<goal>replace</goal>
</goals>
<configuration>
<filesToInclude>${project.basedir}/target/schemas/MySchema.json</filesToInclude>
<preserveDir>true</preserveDir>
<outputDir>target</outputDir>
<replacements>
<replacement>
<token>"Hello":</token>
<value>"Hello World (Json)":</value>
</replacement>
</replacements>
</configuration>
</execution>
<!-- second execution: replace on java file -->
<execution>
<id>replace-for-pojo</id>
<phase>some-phase-after-conversion</phase>
<goals>
<goal>replace</goal>
</goals>
<configuration>
<filesToInclude>${project.basedir}/target/generated-sources/MyPojo.java</filesToInclude>
<preserveDir>true</preserveDir>
<outputDir>target</outputDir>
<replacements>
<replacement>
<token>"Hello":</token>
<value>"Hello World (Java)":</value>
</replacement>
</replacements>
</configuration>
</execution>
</executions>
</plugin>
Source: Configuration for the maven-replacer-plugin on two separate executions

appassembler-maven-plugin add custom entry to classpath

I'm writing a Java-Application which is using some libaries from anonther thirdparty-Application which is running on my server. At the moment im building my App with the appassembler-maven-plugin. This plugin copy my jars (app and dependencies) into the lib folder an generates a shellscript in the bin dir.
The classpath is generated in this shellscirpt. This solution works but i dublicate the dependency-jars (on time in my app and in the thirdparty-Application write the app for). The classpath of my thirdparty-application is set in a systemvariable like $THIRDPARTYAPP_CLASSPATH.
I want to set the dependencies in my pom.xml to provided, so that the appassembler don't add them to lib and classpath and want to add the systemvar $THIRDPARTYAPP_CLASSPATH in my shellscript, so that my app uses the jars from the installed thirdparty-application.
At the moment i'm doing this manually (editing the shellscript after the build) and it works. Is there any method in the appassembler-maven-plugin to add thid systemvar to the classpath automatically?
I couldn't find anything in the documentation and other questions here regarding a similar problem are not well answerd.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.8.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
<configuration>
<assembleDirectory>${project.build.directory}/appassembler</assembleDirectory>
<extraJvmArguments>-Xms512m -Xmx1024m</extraJvmArguments>
<generateRepository>true</generateRepository>
<repositoryName>lib</repositoryName>
<repositoryLayout>flat</repositoryLayout>
<includeConfigurationDirectoryInClasspath>true</includeConfigurationDirectoryInClasspath>
<platforms>
<platform>unix</platform>
</platforms>
<programs>
<program>
<mainClass>${mainClass}</mainClass>
<id>app</id>
</program>
</programs>
</configuration>
</plugin>
You can configure to create an <environmentSetupFileName>setup-env</environmentSetupFileName> which can define a new classpath part via CLASSPATH_PREFIX which should solve your problem.

jboss-as-maven-plugin can't deploy to remote Jboss?

I've tried for days to use jboss-as-maven-plugin to deploy web projects to remote Jboss as 7,but it didn't work. The following is my pom.xml
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.jboss.as.plugins</groupId>
<artifactId>jboss-as-maven-plugin</artifactId>
<version>7.3.Final</version>
<configuration>
<skip>true</skip>
<hostname>127.0.0.1</hostname>
<port>9999</port>
</configuration>
<executions>
<execution>
<id>deploy</id>
<phase>install</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
I have error:
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.jboss.as.plugins:jboss-as-maven-plugin:7.3.
CR1b:deploy (default) on project MessagePushX-RELEASE: Could not execute goal de
ploy on test.war. Reason: java.net.ConnectException: JBAS012144: Could no
t connect to remote://192.168.1.104:9999. The connection timed out -> [Help 1]
[ERROR]
What is wrong?
The error message clearly says it can't connect to "remote://192.168.1.104:9999". Verify that it's the correct configuration and verify your connectivity to that destination.
You can try
telnet 192.168.1.104 9999
from your machine to see if you've got connection.
This may not be the solution you want, but it's one we use.
You can map a network drive to the deploy folder you want your files in, then have maven build it's output to that folder.
For example, on our local machines, maven builds the jar directly in the deploy folder in JBoss.
Another option is to configure JBoss to use an alternate deploy folder in addition to the default. Then have maven build to this alternate folder where JBoss will pick your files up from.
Just a couple of different options to think about if this other one still isn't working for you.
Changes to standalone.xml
Location: (/usr/local/share/jboss/standalone/configuration/standalone.xml)
modified standalone to have auto-deploy zipped true (so as no need to create war.dodeploy file) and auto-deploy-exploded false
<subsystem xmlns="urn:jboss:domain:deployment-scanner:1.1">
<deployment-scanner path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000" auto-deploy-zipped="true" auto-deploy-exploded="false"/>
added jsp-configuration
<subsystem xmlns="urn:jboss:domain:web:1.1" default-virtual-server="default-host" native="false">
<configuration>
<jsp-configuration development="true"/>
</configuration>
added jboss-as-configuration in maven pom.xml
<plugin>
<groupId>org.jboss.as.plugins</groupId>
<artifactId>jboss-as-maven-plugin</artifactId>
<version>7.3.Final</version>
<configuration>
<hostname>192.168.0.105</hostname>
<port>9999</port>
</configuration>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
</plugin>
you should have your jboss instance started from eclipse or outside and bind to same IP instead of localhost or 127.0.0.1.
You can do this either from your command line or from eclipse by changing host to your IP address: 192.168.0.105
After this you can use the following maven goal to redeploy changes after each change. Also please note you might have to use deploy initially and then redeploy.
-e -X jboss-as:redeploy

Categories