Why do I need to add the `Main-Class` attribute ma...
# community-support
j
Why do I need to add the
Main-Class
attribute manually and it is not done automatically by the
application
plugin? The problem is with Docker. If I run it with
./gradlew run
I don't need to setup it to get it working, but when I copy the jar file created by the
installDist
o by the
jar
tasks, it does not work.
p
Afaik because the application plugin specifies the main class inside the generated scripts (installDist). And you can reuse the application property in the jar task configuration to not specify it twice.
j
I was expecting that the application plugin was doing that under the hood, as look like it is not doing that, I would like to now the reason to not do it by default
p
Because in the old world you use a provided web server (eg ibm websphere liberty) and you need to specify the entrypoint in a serverside xml file. And the application plugin is one of the oldest plugins.
til 1
thank you 1
I absolutely agree that it should be changed.
v
No, definitely not.
Especially as it has absolutely nothing to do with any "web server"
👌 1
👍 1
The
application
plugin does not set the
Main-Class
attribute as it does not make any sense to set it.
The
application
plugin is not building a bad-practice fat "runnable" jar.
It builds a proper application distribution archive with your code, your libraries and generated start scritps
Those start scripts are what you use to run the application and where the main class is contained.
Setting the main class in that jar attribute is not really helpful, unless you have no external dependencies at all
j
Setting the main class in that jar attribute is not really helpful, unless you have no external dependencies at all
How should I solve then the problem with Docker?
v
I don't know, as I dont't know what problem you have with Docker
I build the distribution, copy that to the Docker image and use the start script to start it and it works like a charm
At least as far as I remember
j
But with the
application
plugin? Or
shadow
one?
v
Been some while I built a docker image with an app
j
I have been able to remove the manifest by using the shadow plugin
v
applciation
of course,
shadow
is building bad-practice fat jars with no added value, I don't ever use it if I can avoid it
Only if you have bad-practice frameworks that force you to shade your dependencies in one jar I consider using the shadow plugin.
But to run an application in a docker container it brings absolutely 0 value
Actually it even makes things worse
When you do not use it, you can layer your docker image, so that your libraries are one layer and your code is one on top
If only your code changes, only that layer changes and the other can simply be reused
j
But using the jar built with
installDist
fails. Maybe I can try the
.tar
approach
v
The jar does not fail
It fails to be used like
java -jar ...jar
because that is not its intention
You use the start scripts (by default in
bin/
unless you changed configuration) to start the application as documented
The
jar
is just a plain
jar
containing your code, nothing more.
So even if the main class attribute would be set, it would then fail to find its dependencies as also no
Class-Path
attribute is set.
... because that is not the intended way of using it
j
It fails to be used like java -jar ...jar because that is not its intention
Yep, I am doing this
image.png
1
v
You cannot with the result of the
application
plugin ... because that is not the intended way how to use it 😉
What do you want to tell with the screenshot?
j
I was wondering if it was related to the fact that running the
app.jar
will not pick the rest of jar as you commented above about the dependencies.
But I don't have clear how can I solve this
I need to run the executable somehow instead the jar
v
I don't know what you don't understand
As I said, run the start script in bin and all is good
👍 1
thank you 1
j
gotcha! It does not have the
.sh
extension so I was missing that point.
Copy code
build/install/app/bin/app
👌 1
It worked like a charm I don't need any of the workarounds I was using. I am thinking about creating a blog post about this because Google and/or AIs are infected about using the jar or fat jar approach and nobody has mentioned this... and after reading you is obviously that this is the way to do that
p
Regarding Docker layers, there is also jib, that puts the dependencies in one layer, resources in another and classes at the top. And it also integrates with the application plugin. https://github.com/GoogleContainerTools/jib
thank you 1
v
Jib is fine for very very basic cases, yes. As soon as you need anything custom it is very inflexible bullshit. I once tried to use it, hit many road-blocks and pretty quickly stopped using it again.