Spring Boot executable JAR cannot open privileged port as systemd service - spring-boot

I'd like to run my Spring Boot application as a systemd service listening on port 443 directly (not behind nginx/httpd). To do this, I am specifying AmbientCapabilities=CAP_NET_BIND_SERVICE in the systemd service unit like so:
[Service]
User=myapp
ExecStart=/usr/lib/myapp.jar
SucessExitStatus=143
AmbientCapabilities=CAP_NET_BIND_SERVICE
However, the capability seems to be lost when the embedded launch script runs Java. As a test, I substituted my own one-line bash script java -jar /usr/lib/myapp.jar to see if the capability was lost when running any bash script, but that worked. So as far as I can tell, something in the embedded launch script is causing the problem.
With that said, I'm most likely going to drop the embedded launch script in favor of launching Java directly from the systemd service unit, but in case either (1) others have the same problem or (2) this is an actual bug and not just me missing something I did want to at least ask the question.
Cheers!

Related

Can you replace a Spring Boot jar while the application is running?

In our Linux environment applications are restarted periodically (the reasons aren't important here). It would be convenient for us to deploy new versions of an application by copying the application Spring Boot jar on top of the existing (old) jar thereby overwriting it and then simply wait for the application to restart (that is, the JVM running the application to restart).
However, this seems to not work. We get different kinds of errors - sometimes the app just hangs, sometimes we get a ClassNotFoundException. It's as if Spring Boot (or something inside Spring Boot) reopens the jar and expects it to be the same one it was when the application was originally started.
We had a look through Spring's common application properties, but didn't see anything appropriate. Is there a way to make this work? When we were using WAR files we configured the servlet container to unpack the WAR file and run from the unpacked version. Can we do something similar with Spring Boot?
First of all the errors you are experiencing can come from multiple sources. Usually replacing the file from a process is not a big problem as the whole file is loaded into memory before execution. Java is a little bit different, because the actual process that is running is the JVM and it only loads the jar file from disk. The JVM loads classes only on demand, this means if there was any class that was not loaded before it will try to load it and most likely fail, if the jar file is different. In the case of spring boot there are also other resources (such as HTML files) inside the jar file that are dynamically loaded.
You mentioned you are using a linux environment. If you can just replace your startup with a script you can just copy the jar and start it from the copied location:
#!/bin/bash
JAR_NAME="spring-boot.jar"
NEW_JAR_NAME=".$JAR_NAME" # Use an appropriate name here
cp $JAR_NAME $NEW_JAR_NAME
java -jar $NEW_JAR_NAME
rm $NEW_JAR_NAME
Now every time you start the application a copy is being made and started from there. You can replace the original jar and on the next restart the new application will load.
You coud also use rsync instead of cp to avoid copying the same jar twice, if the application is restarted multiple times without changing the jar.
It would be convenient for us to deploy new versions of an application
by copying the Spring Boot jar on top of the existing (old) jar and
then simply wait for the application to restart
Why would you do such a thing to yourself? You are trying solve a usecase that's against best practices, sound like asking for trouble just to avoid an app restart. When you are doing a deployment, you need to make sure the deployment went through, otherwise how will you troubleshoot if something goes wrong in your application, you will have one more variable in hand when you troubleshoot, i,e the uncertainty of current version of the code.
If you are having downtime while deploying (I am assuming thats why you want to limit the restarts), why don't you bring up another instance with the newer version of code and once its healthy shutdown the old one

Best way to start multiple dependent spring boot microservices locally?

Currently my team maintains many spring boot microservices. When running them locally, our workflow is to open a new IntelliJ IDEA window and pressing the "run" button for each microservice. This does the same thing as typing gradle bootRun. At a minimum each service depends on a config server (from which they get their config settings) and a eureka server. Their dependencies are specified in a bootstrap.yml file. I was wondering if there is a way to just launch one microservice (or some script or run configuration), and it would programatically know which dependencies to start along with the service I am testing? It seems cumbersome to start them the way we do now.
If you're using docker then you could use docker compose to launch services in a specific order using the depends_on option. Take a look here and see if that will solve your problem.
https://docs.docker.com/compose/startup-order/

Spring Boot app passing JVM args automatically?

Using Eclipse STS4. Spring Boot 2.4.0 app, this one happens to be Webflux / Netty. Is there a way to specify JVM args in a way that hits in various run scenarios?
debugging / running through STS4
running through mvn command line
running through standalone
I know I can pass in cmd args to all these different ways, but kind of looking for something I can put in my application.properties or something like that? Just trying to avoid having to document it, educate people on how to run it properly, etc.
I've tried various things I found through Google like inlineConfScript, etc. but none of them seem to work.
Have you tried setting JAVA_OPTS in your .conf? See Customizing the start script

How to configure Eclipse-RCP with Spring-Boot

I have an Eclipse RCP(E4) application, which I can start without any problem. Now I decide to connect it to my Spring-Boot embedded Tomcat-server. The Spring-Boot-container runs an H2 as an in memory DB. Running Spring-Boot as "Java Application", I access the data in the DB via a rest-service over the browser.
The problem is, I actually want to embed the Spring-Boot part in my RCP-application. So once I start the application it will start my embedded Sring-Boot tomcat and I can run my CRUD-operations directly from the RCP-UI.
Has anyone got experience dealing with Eclipse-RCP running with Spring-Boot?
P.S: I chose explicitly to not put any code hier, because I don't have any code problem yet. The applications run separately well. I just haven't no clue how to relate them.

run commands per boot via cloud config

I am passing cloud config via --user-data-file argument when starting ec2 instance from canonic ubuntu images.
It works well but the problem is that some of its commands need to run every boot (i.e. when we stop/start or reboot the instance). Is there a way (or section in cloud config) that allows to describe commands that should run on every boot, not only upon instance creation?
You do not need cloud-init to do boot time command execution. Things you want to look at is crontab, upstart scripts, /etc/rc.local and /etc/init.d. There are a lot of options. It depends on the distribution as well.

Resources