Launching Jenkins war from command line

80 views
Skip to first unread message

Ari Maniatis

unread,
Jun 18, 2015, 4:14:28 AM6/18/15
to jenkin...@googlegroups.com
Jenkins (and Hudson before it) has implemented a neat trick to launching the app without a container (tomcat, jetty, etc) being launched first.

java -jar jenkins.war


I'm trying to do the same on another project, but can't figure out how this trick works. I understand some parts. Add a line to the MANIFEST...

'Main-Class': 'Main'


Where Main.class is the main class that launches the application and it is found in the root of the war, outside the WEB-INF folder. But I've done the same and I can't get my project to behave in the same way. Is there more to this launch process?

Is Winstone involves in some way? I see it is a lightweight container, but then the full Jetty deployment is also found inside Jenkins, so I'm not understanding the intersection between the two and whether it is about this way to launch the war.


I know this isn't about development of Jenkins exactly, but I'm hoping someone might be able to share some pointers.


Thanks
Ari

Ben Castellucci

unread,
Jun 18, 2015, 6:12:14 AM6/18/15
to Jenkins Developers

I'll start by stating that i don't know how Jenkins does it exactly - you'll have to poke around the source to figure out its classloading tricks.

That said, i do know how you do it without special classloading tricks.

It is 2 parts - first part is to extract all jars involved in the servlet container to one directory, then add your main class with some lines of code to start up an instance of the container and reference that main class in your manifest.

Then jar up that entire directory and you should be able to do something like:

  Java -jar my.jar

Once that is working, on to the second part...

Go back to your uber directory and start adding your web stuff (WEB-INF, JSPs, etc.) So it starts looking like a web app as well. This stuff lives side by side - the entire thing looks like a jar file and a web app at the same time.

Then go back to your main class and here is the tricky part - you need to get the absolute path to the currently executing jar file and deploy it to your container instance (look into protection domain).

Also you will need to choose a file system directory somewhere to have the container extract the jar (war) file it is deploying since undoubtly you have jars in your WEB-INF/lib and without special classloading tricks those will have to come out of the jar (war) and onto the file system before they can be loaded with the running web app.

Then you jar up that uber directory and give it a .war extension and you should be able to do something like:

  Java -jar my.war

And it should fire up the container then deploy itself and, as part of the deploy process, it will extract web-inf/libs to whatever file system directory you told it.

You should also be able to just drop my.war into any servlet container and run it like a regular web app - all that stuff from the container you bundled will be ignored.

Ok, that all said, i think Jenkins has a special classloader that can load jars within jars and can therefore skip the step where all the container jars get extracted to the uber directory. Instead it can just include the jars directly.

Anyway, there are several examples out there on how to embed jetty and also how to make an executable war with jetty.

The explanation above should get you going your search.

Thanks,
Ben

--
You received this message because you are subscribed to the Google Groups "Jenkins Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-de...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-dev/bb024b0c-f8ed-41ec-bb3a-102cc632e636%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ari Maniatis

unread,
Jun 18, 2015, 7:28:01 PM6/18/15
to jenkin...@googlegroups.com
On Thursday, 18 June 2015 20:12:14 UTC+10, Ben Castellucci wrote:

It is 2 parts - first part is to extract all jars involved in the servlet container to one directory, then add your main class with some lines of code to start up an instance of the container and reference that main class in your manifest.

Then jar up that entire directory and you should be able to do something like:


Actually that's what I'm trying to escape. The whole fatjar approach is what I do now, but it causes some problems including issues with log4j custom appenders. Jenkins/Hudson is the only application I've seen which launches directly from the war, which is a neat trick.

Cheers
Ari
Reply all
Reply to author
Forward
0 new messages