I am working on Spring Boot 3 project and trying to build a native image using GraalVM native build tool. I have added the native image plugin (org.graalvm.buildtools:native-maven-plugin) in pom.xml. I am confused about which of the below two commands to use to build a native jar.
mvn -f ./pom.xml -Pnative package
or
mvn -f ./pom.xml -Pnative native:compile
Both are generating the jars in the target directory and adding the graalvm-reachabilty metadata. I want to know how these 2 goals differ and which one should be used to build a native jar.
Related
In npm we have the option to define project specific scripts in the package.json file as described here.
What is the best tool/approach to this with maven? I'd like a way to write cross-platform, reproducible scripts with minimal setup.
Example scripts and the raw commands:
Build the project into a JAR file, skipping tests, and then deploy as part of a docker-compose deployment
mvn package -Dmaven.test.skip=true
docker-compose up --build -d
Rebuild and replace the running container in the docker-compose deployment
mvn package -Dmaven.test.skip=true
docker-compose up -d --no-deps --build spring
Build the project and run tests without deploying
mvn clean install
These commands can be a pain to remember and this is a project that will be used by many students with limited maven and docker experience. So a tool that's easy to install and makes creating scripts that 'just work' when pulling the repository would be great.
I have a Java Spring Boot web application that I'd like to containerize using Docker. I'm having trouble getting the mvn install command to work during the Docker build process because my project depends on some other Maven projects I've written that are installed in my local /.m2 folder but aren't available in the Maven central repository. I'd like to avoid adding these local projects to the public Maven central repository because they exist specifically to support this Spring Boot application and I'd like to keep them private.
If I wasn't using Docker, I could get around this problem by building a JAR with dependencies then deploying that .jar file. Is there any way for me to include these local dependencies in my Docker build process?
Here's the simple Dockerfile I'm trying to run:
# Step 1: Build with Maven
FROM maven:3.5-jdk-8-alpine
COPY . /usr/src/myapp
WORKDIR /usr/src/myapp
RUN mvn clean install
# Step 2: Run jar file with Java
FROM openjdk:8-alpine
WORKDIR /usr/src/myapp
COPY --from=0 /usr/src/myapp/target/myapp-1.0-SNAPSHOT.jar ./myapp.jar
ENTRYPOINT ["java", "-jar", "myapp.jar"]
I run this build command:
docker build -t myspringapp .
And it errors with the following message:
[ERROR] Failed to execute goal on project server: Could not resolve dependencies for project
com.website:myapp:jar:1.0-SNAPSHOT: The following artifacts could not be resolved:
com.website:dependency1:jar:0.1.0, com.website:dependency2:jar:0.1.0,
com.website:dependency3:jar:0.1.0:
Could not find artifact com.website:dependency1:jar:0.1.0 in central
(https://repo.maven.apache.org/maven2) -> [Help 1]
As an alternative question, can I just run the mvn clean install command on my development machine to produce the jar file then skip the whole Maven build part of the Docker image? Will my container still be able to replicate itself in an auto-scaling scenario? Do I lose anything by building the project separately from its Docker image/container?
Easiest thing to do would be to just put your .m2 directory in the Docker build context, and make sure the build stage of the Dockerfile does a COPY of .m2 to wherever the base maven image is expecting it to be. That way, the build stage doesn't need to download your private JAR files.
To answer your alternative question, yes. It's not very 12-factor, but it's definitely doable to do the JAR build outside of the Docker ecosystem, then just COPY the pre-built JAR file into the image.
I have a Spring project and a corresponding JAR file.
After i change something in one of my Java class files and run mvn package, building my Docker image of that project later is using the cached JAR.
Only if i run mvn clean package, my Docker build process does not use the cached JAR:
Step 4/6 : COPY app/target/app-${VERSION}.jar app.jar
---> 19987e6dda16
Is that expected?
Do i always have to run mvn clean package instead of mvn package after changing some code?
Suppose that we have a Java application, rather than a library, which is available through Maven central. For example, one such project is jol, which has its corresponding CLI interface in Maven central.
As far as I can tell, the main difference from a library is that the corresponding JAR file contains a class with an appropriate main() method and, optionally, a related Main-Class: header in the JAR manifest. If such an artifact is used as a dependency on a project, Maven will happily download the JAR file to the local repository along with its dependencies, as it does for any other artifact.
Is it possible to use Maven to execute such an application directly, without setting up a Maven project?
The exec:java plugin works nicely for local projects by setting up the JVM classpath so that dependencies are available. The user does not have to worry about JAR or .class file locations and such. Unfortunately, from what I can tell, it also requires an enclosing Maven project, so it cannot be used from an arbitrary command line prompt.
No, Maven will not do what you are asking for. It is a build tool, intended to build a Java project based on it's pom.xml file which describes the project.
So, you can't run a maven build without a pom.xml file.
And if you have a pom.xml, then by definition, you have 'set up a Maven project'.
As #DaveNewton says, you should be able to set up a very small pom.xml with the dependency for the jar file in question, and the exec-maven plugin. I'm afraid that it's just not going to get any simpler than that.
A hacky solution working with Maven 3 would be to use the Maven Dependency Plugin in combination with the Maven Help Plugin to resolve the local repository path:
# Download JAR from Maven repo
mvn dependency:get -DremoteRepositories=http://repo1.maven.org/maven2/ \
-DgroupId=some.group.id \
-DartifactId=some-artifact-cli \
-Dversion=1.0.0 \
-Dtransitive=false
# Resolve local repository path
MVN_REPO=$(mvn help:evaluate -Dexpression=settings.localRepository -q -DforceStdout)
# Execute JAR from the local repository
java -jar $MVN_REPO/some/group/id/some-artifact-cli/1.0.0/some-artifact-cli-1.0.0.jar
I am using Maven to manage a console application project. On my machine, I type mvn exec:java and Maven handles everything. What I want is, however, to execute the same application on a different machine without the help of Maven.
In NetBeans, Ant projects have a dist directory with all the necessary files. All you have to do is to type java -jar dist/App.jar. How can I make Maven generate such distributable directory or archive?
PS: Although seems relevant, this is not a duplicate of Create a standalone application with Maven.
I have used in maven.
http://mojo.codehaus.org/appassembler/appassembler-maven-plugin/
The Application Assembler Plugin is a Maven plugin for generating scripts for starting java applications. All dependencies and the artifact of the project itself are placed in a generated Maven repository in a defined assemble directory. All artifacts (dependencies + the artifact from the project) are added to the classpath in the generated bin scripts.
and http://maven.apache.org/plugins/maven-assembly-plugin/
The Assembly Plugin for Maven is primarily intended to allow users to aggregate the project output along with its dependencies, modules, site documentation, and other files into a single distributable archive.
You can build an executable jar file with the maven-jar-plugin; more info on their examples page here: http://maven.apache.org/shared/maven-archiver/examples/classpath.html
That will simply create an all-in-one jar that can be executed through java -jar