Hello. I'm collecting dependencies in my jar file ...
# gradle
m
Hello. I'm collecting dependencies in my jar file in order to create a Docker image. I'm using:
Copy code
jar {
    // ... Manifest stuff

    from {
        configurations.compile.collect {
            it.isDirectory() ? it : zipTree(it)
        }
    }
}
This works with my test project but has no effect in my actual project. What could be the cause?
v
Why do you build a fat jar at all? Better build a proper distribution using the
application
plugin that you then can but into the docker image for running it. Imho 98.7 % of fat jars are evil, a too wide-spread bad practicy, and an abuse of Java functionality with absolutely no added value which in some cases even cannot work and can also all too easily be done wrongly and break things that would otherwise work fine.
💯 1
You can for example make sure
distTar
task is run before the docker image is built and then use
ADD <your-app>.tar /opt/
in the Dockerfile to copy and unpack the built distribution tar into your docker image and then you can use the generated start script in the
bin
directory as entrypoint.
💯 1
m
Basically because I didn't know any better! I'm a docker newbie and I'm not an expert of gradle or IntelliJ IDEA. Thanks for the suggestion. In particular, your last message provides the general direction that I needed. I'll try to follow it. One additional thing: how do I make sure
distTar
is run when I execute the application with IntelliJ IDEA?
v
You don't want that,
distTar
is for building a distributable archive, not for running from the IDE.
You can run the
run
task from IJ, which will assemble distribution exactly like in the archive, just exploded in
build/install/
and runs it.
Or you just run your main class in IJ using the run button, unless you do something fancy it should work just the same
m
That's what I do normally, but I expect that I will be running the application locally in Docker and debugging in it before I deploy it on the cloud. There is a "Run" icon in the border of the Dockerfile editor and there are new Docker run/debug configurations in IntelliJ IDEA. I'm wondering how that will work together.
I managed to run a test project following your directions. I can start it from IDEA, too. Debugging does not work so far, as per my fears. I'll work on that now.
I will probably have to pass options to the JVM to enable the debugging service.
v
Yes, the generated start script evaluate environment variables for JVM parameters, one general
JAVA_OPTS
and one specific to your application
<YOUR_APPLICATION>_OPTS
that you can set to enable debugging for example. If you don't need it 100% like in production but it is sufficient if the code is run in the target docker container, the new run targets feature of IntelliJ 2021.1 might be what you need. With that you can run and debug nicely within Docker containers, on remote SSH hosts, ...
👍 1
m
I found this article: https://blog.jetbrains.com/idea/2019/04/debug-your-java-applications-in-docker-using-intellij-idea/ I'm getting:
Failed to deploy 'decker2 Dockerfile: x/y/z/Dockerfile': org.apache.commons.cli.ParseException: Unrecognized argument: null
Figure 1 is how I setup the remote debugging configuration. Figure 2 is how I (didn't) setup the "Launch Docker before debug" task. What's missing? Am I supposed to copy the JVM arguments somewhere?
v
You are aware that I talked about a new functionality in version 2021.1 that for sure is not contained in a blog from 2019?
Besides that, I can hardly guess where your error message originates from. But even if you want to follow that manual road then yes you have to give the debug arguments to your started process of course, probably in your dockerfile.
m
Yes, remote debugging with Docker and run targets are two different features. I'm going to try both. Having to manually change the Dockerfile when debugging kind of defeats the purpose of having a debugging configuration in the IDE. I suppose that there is a way to pass those arguments in the "Configure Docker" panel. I still don't understand what it is, if it exists. I wonder if the error message and this lack of configuration are related. The error message is obscure, unfortunately but that's all that there is.
v
Well, from the wording I'd say either your program or whatever you call in that docker container uses commons-cli for parsing arguments and you give it literally
null
as argument which is not recognized as a valid parameter. Regarding the remote debugging approach, as I said, it depends on how you start your application. If you for example use the result of the
application
plugin, you can set the environment variable
<YOUR_APPLICATION>_OPTS
(look inside the generated start script for the exact one) or the environment variable
JAVA_OPTS
. Actually independent of how you start your application, you can also always set the environment variable
JAVA_TOOL_OPTIONS
which is picked up by the JVM automatically not matter how you start your application. I'm sure you can configure environment variables in the docker run configuration.
m
Additionally, I think "Run targets" is present only in IDEA Ultimate, even if IntelliJ didn't specify that in the announcement: https://www.jetbrains.com/help/idea/2021.1/run-targets.html I'm using the Community edition.
v
Ah, yeah, right. I tend to forget that not everyone uses Ultimate. 😄 I sometimes tend to think, that you either have Ultimate because it is free if you are student or similar, or can afford the 89 € per year to get the better functionality and support the awesome product if your employer doesn't pay for you. g So if you are on community, you need to resort to the manual remote debugging, yes.
Btw. watch out for the next TeamCity plugin contest. Usually every valid submissing and be is even just a tiny thing, is eligible to get one-year of any JetBrains IDE. (Which also means you can use that version perpetually through the fallback license) 🙂
m
I'm a pre-seed funding start-up, this is my first large JVM project and I wasn't even sure of what technology stack I was going to use. So I didn't think of paying for IDEA Ultimate. I may do that in the near future, since I'm probably sticking to Kotlin for all platforms in most of the cases. Thanks again for your help. With your first messages you probably made me save several hours.
v
You're welcome. 🙂 It wasn't a complaint that you don't pay btw. using community version is fine if it suits your needs, just in case it read like that. 🙂
f
Use https://github.com/GoogleContainerTools/jib for building docker images and get rid of all and any complexity related to it. This also works perfect in a Gradle monorepo and building tons of containers in
org.gradle.parallel
.
m
@Fleshgrinder Thanks. That's an useful link.