Developing Java (Maven) application on Docker container - java

For a new Spring project I'd like to setup a Docker container to build + run + debug my application.
At the moment I'm using this Dockerfile:
FROM maven:3.6.2-jdk-8-slim
COPY . /app/
WORKDIR /app/
RUN mvn clean package
FROM maven:3.6.2-jdk-8-slim
COPY target/app.jar app.jar
ENTRYPOINT ["java","-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005", "-jar","/app.jar"]
EXPOSE 5005
In the first step the project is built. In the second step the application is run exposing a 5005 port for "remote" debugging.
Then from my IDE (IntelliJ IDEA) I'm configuring a remote debugging configuration to execute debug on the container.
As you may guess is a bit awkward to execute these steps for every little edit I'd like to debug in the project.
So, I'm wondering if there's a more practical approach using IntelliJ to automatically build and attach the debugger to my application just like when developing directly on my dev machine...

First of all, you can open a pom.xml right from IntelliJ and run the application without the need to run maven (IntelliJ has an excellent maven plugin).
Since you're running it as a java -jar you don't even need an ultimate version of IntelliJ.
Now this is how we develop usually, even before maven. You can run mvn clean package locally as well if you want to, say, check that the tests are run (again, you can also do that in Idea). And when you push your changes create a docker and deploy on server.
This is by far the best solution I can recommend. The way you've described in the question suites more to debugging the remote servers (read ready environments).
If you absolutely need this way, you still can use HotSwap feature of JVM for small changes (as longs as these changes are inside the method): While connected via Remote Debugger, right click and "Recompile" the class that has a change. It will be automatically loaded to remote JVM so that you don't actually need to trigger all this process.
You also don't have to run all the tests in maven (mvn clean package -Dmaven.tests.skip)

A couple of ideas that you can implement:
Use CI/CD to build your docker images
Instead of offloading this work to docker files, let your CI/CD pipeline to build your artifact and then pack it into a docker image ( you'll have more control over the process ). Finally, you can also deploy it to a targeted environment.
Use IntelliJ to run and debug your project on the DEV machine
You gain almost no benefit by running your project using Docker on your DEV machine, only a lot of hassle.

Related

Run Maven Project (with ant) in a single go using Remote Debug Configuration of IntelliJ

I have a Maven Project, Ant Project which are somehow coupled. If I have to make any change in maven project and test it I have to do following steps every time, which is very time consuming.
Steps
ant stopserver
mvn install
ant startserver
Access it on localhost:8080
And to debug anything I have to create a Remote Debug Configuration which connects to port 8000 and start ant server in debug mode.
All this is new to me as I have only worked on microservices based out of maven when there is a #SpringApplication class with main method which I could directly run/debug. In this project, there is no class with main method. It's a legacy spring mvc project.
I seriously want some way to do the same with current project. I tried going though the build.xml but ant steps are hardly taken less than a second.
Is there a way possible? Can it run like a normal maven project? Ant is probably building some db and ui parts (not very sure). But I only work on Java side.
Please help. Anything that could get rid of me having to run mvn install with every small change would also be helpful. To reduce the time taken by mvn install I used the script from this answer here and added that as well, as one of the before launch steps but the time taken is still the same.
I have tried following post but it did not work for me How to build maven project with ant script?
Open the lid and find out what exactly ant startserver does, and then create a launch configuration in your IDE that does the same thing. You might be able to cheat a bit and investigate the process in the operating system using its tools to get the invocation commandline.
Then run that launch configuration in the Debugger and tell your IDE to tell the JVM to hotswap newly compiled classes.
You should now have a much improved experience.
You may want to take the opportunity to teach Maven how to launch your server as that might enable the IDE to pick this up directly.
I was able to achieve at least one click start by Adding ant targets as part of the "Before Launch" inside "Run/Debug Configurations". To reduce the time taken by mvn install I used the script from this answer here and added that as well, as one of the before launch steps.
By enabling Logs, this also became user friendly.
Here is how my config looks like now,
However, I still have to do maven install.

How to build, deploy and run Java application on JBoss WildFly from the command line?

My team is working on a Java application that runs on Jboss WildFly, using Maven to resolve dependencies and Primefaces.
We're using Eclipse to build, deploy and run the server. Eclipse does most of the work, building the WAR file, deploying it to server and running it.
Now we need to create an script that performs all those steps because it has to run on remote server.
.
The steps would be something like this...
1 Run Maven:
$M2_HOME/bin/mvn clean install
2 Build project to a war file
3 Deploy war file into the WildFly deployment folder
$WILDFLY_HOME/bin/jboss-cli.sh --connect --command="deploy --force [PATH_TO_WAR]"
4 Start server
$WILDFLY_HOME/bin/standalone.sh
.
I can perform every step but once the server is running it don't seem to be any changes in the application. I think this is because the WAR file has to be built optimizing it for JBoss. Eclipse has a way to do this when exporting the project. I need to know how to do that from command.
EDIT:
The real problem is that Jboss is not updating the published project when i run it from bash script. I thought it was because i had to build it on a specific way. I was wrong. The build is fine, just running Maven the deploy is done. The thing is that even if i rebuild project and redeploy it, server doesn't seem to notice at all.
I've tried deleting tmp, lib and data folders from standalone folder, and nothing happens. I also deleted standalone/deployed sub files and folders and got the same result.
The only way i achieve the result i'm expecting is getting into Eclipse, go to Servers tab, right click on JBoss Wildfly and click on 'Clean...'. This options seems to clean cache, rebuild and re publish the application in a right way that i don't know. I didn't find any answers on google.
eclipse server clean option
Give a look on Eclipse war export: optimize for a specific server runtime.
Quoting from #Konstantin Komissarchik's answer :
Eclipse itself doesn't do anything with that option. What happens is
dependent on a particular server adapter. Many of the adapters don't
do anything with this option either, but they might in the future.
If a server adapter does support export optimization, it has the
option of displaying custom options beneath that pop-up list of
runtimes, so that's a good cue to use to see if something will
actually happen.
So taking in consideration that in your provided image there is no custom options below Wildfly 9 selection, I am pretty sure that this option does not perform any optimization at your exported war so you can totally omit it in your new build-deploy process.
How can i build the war file from command, knowing it will have to run on Wildfly?
We are also deploying applications for a long time on several versions of Widlfy with the same approach as you are planning to, without the optimization thing. I can ensure you that we have not faced any performance issue.

Debugging Thorntail Services in Eclipse?

I've got several microservices projects that I'm developing using the Thorntail framework. I'm writing my code using Eclipse. In the past, I've done all of my development using the Wildfly app server, and Eclipse made debugging these apps dead simple. Right Click->Debug As->Debug On Server. Done. Now that I'm using Thorntail, I'm not quite sure how to do it.
From the command line, I would start my Thorntail projects using:
mvn thorntail:run -Dthorntail.useUberJar # Project 1
mvn thorntail:run -Dthorntail.useUberJar -Dthorntail.port.offset=1000 # Project 2
That gets everything up and running, and listening on ports 8080 and 9080. However, the services are not in debug mode and I didn't launch these through Eclipse.
I know I can Right Click->Debug As->Maven Build... and then create a new debug configuration. I've done so, with my goals corresponding to the mvn commands above. However, when I do so no debugger is automatically attached, so breakpoints and such don't work. I'm sure I'm missing a step somewhere, but this is functionality I haven't tried to use before so I'm lost. Any recommendations?
The mvn thorntail:run accepts a system property thorntail.debug.port with a port number. For example, if you run
mvn thorntail:run -Dthorntail.useUberJar -Dthorntail.debug.port=5005
the Java process will wait for remote debugger connection and only then will it continue.
I don't use Eclipse, but I'm pretty sure configuring a remote debugging session isn't hard.
Execute the uberjar with the following parameters. Ensure that all the parameters are specified before the name of the uberjar on the line.
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=$PORT_NUMBER -jar $UBERJAR_FILENAME
$PORT_NUMBER is an unused port number of your choice. Remember this number for the remote debugger configuration.
$UBERJAR_FILENAME is the uberjar.
suspend=y ensures that JVM will pause and wait for remote debugger connection before it starts the application.
To remote debugging it using Eclipse IDE you have to open Eclipse, open source code of the targeted application and create a debug configuration ("Remote Java Application") by specifying the targeted host and port. After this, hit "Debug" button and proceed with the remote debugging.

Running Integration tests from a Docker image for Java project

I am new to Docker and currently working on a project which uses docker for build and deployment. I have installed Docker for windows on my Windows 10 machine and currently running docker in windows environment.
I am using Jenkins for creating the docker image for a project which has Integration tests coded inside it.
I need to create new Job in Jenkins which will take docker image from previous job and run Integration tests on this image and not on the code base. I am not sure if we can do it for Windows. I have searched online but have not found any articles or tutorials which explain how to achieve this.
Can someone help me with this problem or guide me to a solution which i can refer.
Thanks
Vikeng
Your question is a few months old, but still :)
You can have a look at the Fabric8 Docker Maven Plugin https://dmp.fabric8.io/
It integrates very well with the Maven workflow: you describe how to build your image (with a DockerFile or in the pom directly), as well as how to run it (in a 'docker run' manner or with a docker-compose.yaml). Of course, Windows is supported, since it is your use case :)
Then, the phases of the plugin integrate well, the build of the image is made at the 'package' phase, and the containers are started at 'pre-integration' and stopped and removed at 'post-integration'.
One small thing to remember is if you have a multi-module project, the integration tests are run by module, so if you have several images that integrate together, make sure to define them in the same pom.
Hope this helps

Which java server to run a jar application?

I made a java program which runs unit test on my website.
I need the unit test to keep running during the day while I watch the log.
For this, I search a java platform on which I can run my soft. Openshift will be the best because it's easy to install and maintain.
However I will often modify this soft and if the java project could be built whenever I made a commit it will be the best. That's why I think to Jenkins, but I don't know if it is a good way to run a jar from a jenkins server whereas it is made to do build.
I tried JBoss and tomcat by wrapping my programs into an Enterprise Application Client but I can not run and check the log of the program from a web interface.
Currently my project is a Java Application, using MySQL, hibernate, maven and git.
What would be the best option for you ?
Thanks.
Florian C.
Finally, here is my soluce.
I use Jenkins.
When I push on Jenkins, my project is automatically built and ran using a shell script.
If the build or the run fails Jenkins sends me the command output by mail.
Else, every day, the project is run (using the cron of jenkins) and the console output is sent to me by mail, so I can check the result of my test.

Categories