`no main manifest attribute, in /my_app.jar` was t...
# ktor
t
no main manifest attribute, in /my_app.jar
was the error
r
Where does
my_app.jar
come from? Aren't you running
canti.jar
?
t
sorry i replaced the name ona ccident when i copied it over
but yes you are correct it is
canti.jar
r
Are you sure the right jar is getting copied into the container?
Have you exec'ed into the container to verify it?
t
checking now
you cannot exec into the container since it never starts
r
Just start it by overriding the command executed to a shell e.g.
docker run -ti mycontainer /bin/sh
. Since you are using `ENTRYPOINT`and not
CMD
you probably need to use
--entrypoint
to override it.
t
like so?
docker run -it 87208166d967 /bin/sh --entrypoint
r
Probably more like
docker run -it 87208166d967 --entrypoint /bin/sh
t
hmm i get
Unable to find image '87208166d967:latest' locally
but the image is there
Copy code
87208166d967        canti:1.0.1                  "sh -c 'java $JAVA_O…"   6 minutes ago       Exited (1) 5 minutes ago                                                                                                 cocky_varahamihira
r
I think you are looking at containers, not images
docker images
t
oh man you are right my apologies
still get the original message of
no main manifest attribute, in /canti.jar
r
Try:
docker run -it --entrypoint /bin/sh mycontainer
. It's easier to override
CMD
rather than
ENTRYPOINT
. I'd switch to
CMD
here unless you had a specific reason for using
ENTRYPOINT
.
And don't start a shell unnecessarily as that will mess up signal handling i.e. get rid of your
sh -c
bit.
t
cool! i was able to get in now
ok i will take notes of those
i see the jar in
its called
canti.jar
r
All right, just try running it inside the container. What do you get?
t
Error: Could not find or load main class canti.jar
r
What did you run exactly?
Give me the command line
t
i first did
java canti.jar
then
java -jar canti.jar
same message both times
ah wait no sorry
java canti.jar
gave
Error: Could not find or load main class canti.jar
and
java -jar canti.jar
gave
no main manifest attribute, in canti.jar
r
And when you run the same jar outside the container in the same way
java -jar canti.jar
, it works?
t
when id run locally id use intellij
r
Ah, well it goes back to my original point then: get your jar running outside of docker first. Using
java -jar ...
.
t
ah ok
i will attempt that first then
sorry for the misunderstanding
r
If you're open to running it differently, you can use the distribution script the gradle application plugin creates for you. For example, here is the end of a dockerfile from one of my projects:
Copy code
WORKDIR /foo
ADD distributions/foo.tar /
CMD ["./bin/foo"]
Those start scripts the plugin creates take care of all sorts of useful stuff like JVM options and other stuff you can now pass in as environment settings (which is a common way to configure the runtime env in Docker deployments).
But in any case, get it running first outside Docker. 🙂
m
i have a feeling if you run
java -cp  canti.jar io.ktor.server.netty.DevelopmentEngine
(or whatever it is) you will also see some class loading/class path issues too in addition to what @rocketraman already mentioned, about the distribution script, https://github.com/johnrengelman/shadow is another option for "fat jar" type packaging
r
Fat jars are pretty unnecessary if deploying via Docker. The Docker container already contains everything it needs to run the app, so adding a fat jar is just extra packaging overhead for no particular benefit.
Which is also why executing your app via
java -jar
isn't the best idea either.
java -jar
was created to make things simple for end-users, and IMO is not the right way to package and deploy a server-side application.
m
there are definitely tradeoffs
r
@mkobit What would you see as a benefit of the fat jar approach if your execution target is a Docker container?
m
common packaging format i think can be an easy starting point since lots of tools already support it mostly out of the box (spring boot, shadow, vertx +shadow) for example, if your organization has lots of different java services and wants to to have a hook into the build/deploy process you could share a "baseline" docker image with a base entrypoint and some environment variable knobs. i think things like
jlink
in java 9, docker image layering, pods in kubernetes, better distribution mechanisms (like https://docs.gradle.org/current/userguide/java_library_distribution_plugin.html) all offer different approaches with different improves, but i think the "fatj ar" approach is one that is simple and easy to get moving fast with since it is a pattern that has been around for a while. i havent had the opportunity to do much development with java 9 so it might be different there, though what are your thoughts?
t
ah HA! i figured it out i think
had to add this then rebuild and redockerize
Copy code
jar {
    baseName = "canti"
    manifest {
        attributes 'Main-Class': mainClassName
    }
}
@rocketraman if you are interested ^
r
@tjb Glad you got it figured out!
t
thank you for your insight as well!
👍 1