question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Containerize an executable WAR

See original GitHub issue

Description of the issue: Impossible to run an executable WAR

Expected behavior: Override the default WAR containerization behavior to permit to run executable WAR

Steps to reproduce:

Environment:

jib-maven-plugin Configuration:

...
<plugin>
   <groupId>com.google.cloud.tools</groupId>
   <artifactId>jib-maven-plugin</artifactId>
   <version>${jib-maven-plugin.version}</version>
   <configuration>
      <from>
         <image>openjdk:8-jre-alpine</image>
      </from>
      <to>
         <image>jhipster:latest</image>
      </to>
      <container>
         <entrypoint>
            <script>/entrypoint.sh</script>
         </entrypoint>
         <ports>
            <port>8080</port>
         </ports>
         <environment>
            <SPRING_OUTPUT_ANSI_ENABLED>ALWAYS</SPRING_OUTPUT_ANSI_ENABLED>
            <JHIPSTER_SLEEP>0</JHIPSTER_SLEEP>
         </environment>
         <useCurrentTimestamp>true</useCurrentTimestamp>
      </container>
      <extraDirectories>
         <permissions>
            <permission>
               <file>/entrypoint.sh</file>
               <mode>700</mode>
            </permission>
         </permissions>
      </extraDirectories>
   </configuration>
</plugin>    
...

jib-gradle-plugin Configuration:

jib {
    from {
        image = 'openjdk:8-jre-alpine'
    }
    to {
        image = 'jhipster:latest'
    }
    container {
        entrypoint = ['/entrypoint.sh']
        ports = ['8080']
        environment = [
            SPRING_OUTPUT_ANSI_ENABLED: 'ALWAYS',
            JHIPSTER_SLEEP: '0'
        ]
        useCurrentTimestamp = true
    }
    extraDirectories {
        permissions = ['/entrypoint.sh': '700']
    }
}

Log output:

Additional Information:

The presented issue (executable WAR) seems orthogonal to the 0.10.0 WAR behavior but is a neat feature provided by Spring Boot.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:15 (9 by maintainers)

github_iconTop GitHub Comments

3reactions
chanseokohcommented, Dec 5, 2018

I’ve played around with some demo app generated by JHipster. I tried to generate as much a simple app as possible, but still not a small app in that it uses MySQL, in-memory H2 persistence, Ehcache Spring cache abstraction, Angular, etc., which actually requires using docker-compose to make the Jib-built image to talk to the MySQL Docker container. The point is, it is not a toy hello world app.

The Jib configuration for my demo app looked something like this:

<configuration>
  <from><image>openjdk:8-jre-alpine</image></from>
  <to><image>demoapp:latest</image></to>
  <container>
    <entrypoint>
      <shell>sh</shell>
      <option>-c</option>
      <arg>chmod +x /entrypoint.sh &amp;&amp; sync &amp;&amp; /entrypoint.sh</arg>
    </entrypoint>
    <ports><port>8080</port></ports>
    <environment>
      <SPRING_OUTPUT_ANSI_ENABLED>ALWAYS</SPRING_OUTPUT_ANSI_ENABLED>
      <JHIPSTER_SLEEP>0</JHIPSTER_SLEEP>
    </environment>
    <useCurrentTimestamp>true</useCurrentTimestamp>
  </container>
</configuration>

src/main/jib/entrypoint.sh is something like this:

#!/bin/sh
  
echo "The application will start in ${JHIPSTER_SLEEP}s..." \
  && sleep ${JHIPSTER_SLEEP}
exec java ${JAVA_OPTS} \
  -Djava.security.egd=file:/dev/./urandom \
  -cp /app/resources/:/app/classes/:/app/libs/* \
  "com.example.demoapp.DemoappApp"  \
  "$@"

(Side note: one example of someone directly copy-and-pasting the current classpath.)

It is certain that the app needs to be containerized in the usual, non-WAR way. In that sense, one could argue that the project should not have <packaging>war</packaging>. However, it also configures the maven-war-plugin, and when the packaging is war, the end effect is that ./mvnw package will be able to create a WAR under the build directory, which will probably be JHipster’s intention. One could argue that you can do ./mvnw war:war still after changing the packaging to jar, but looks like Spring Boot is also checking the packaging type, so it does not produce an executable WAR. Even if there is a way to configure Spring Boot to produce an executable WAR when the packaging is not war (I am a bit skeptical actually) and run some command separately for that purpose, it does not sound fair to have JHipster to switch the packaging just because of Jib. In the current settings, JHipster will not be able to upgrade Jib.

Considering these, and to have good support for JHipster, I think it’s worth adding some means to force WAR or non-WAR containerization, which can also cover #1302.

1reaction
ST-DDTcommented, Mar 27, 2020

If your project uses the war packaging (spring-boot), then you can run it without any changes like this:

<configuration>
	<from>
		<image>adoptopenjdk/openjdk11:alpine-jre</image>
	</from>
	<to>
		<image>...</image>
	</to>
	<container>
		<appRoot>/app</appRoot>
		<entrypoint>
			<entrypoint>java</entrypoint>
			<!-- Start of JVM flags --->
			<entrypoint>-Dlogging.config=/config/log4j2.xml</entrypoint>
			<entrypoint>-Dspring.config.additional-location=/config/</entrypoint>
			<!-- End of JVM flags --->
			<entrypoint>-cp</entrypoint>
			<entrypoint>/app:/app/WEB-INF/classes:/app/WEB-INF/lib/*</entrypoint>
			<!-- use your actual main class, not the spring.boot.WarLauncher -->
			<entrypoint>${mainClass}</entrypoint>
		</entrypoint>
                [...]
	</container>
</configuration>

There is no need to use the wrapping tomcat or jetty images for that.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Deploying the Executable WAR - Dependency-Track
An executable WAR is a traditional Java Web Archive (WAR) that is packaged in a way where it can executed from the command-line....
Read more >
Advice deploying war files vs executable jar with embedded ...
My question is, coming from an environment where we have deployed our (up to this point mostly Struts2) applications to a single tomcat ......
Read more >
Deploying Spring Boot War in Tomcat running in Docker
First things First — Lets create a WAR file. As you know, Spring Boot based application by default creates executable JAR. We need...
Read more >
Deploying a Java War in a Docker Container - Baeldung
In this tutorial, we'll learn to deploy a Java WAR file inside a Docker container. We'll deploy the WAR file on Apache Tomcat,...
Read more >
Packaging your .jar or .war files into a Docker container
Java/Spring courses & guideshttps://www.marcobehler.com▻ Newsletterhttps://bit.ly/2K0Ao4F▻ YouTube subhttps://bit.ly/2lVExgmYou learned ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found