Skip to content
This repository has been archived by the owner on Aug 2, 2024. It is now read-only.

Deploying Thin Jars with Google App Engine Plugins #399

Closed
SudharakaP opened this issue Sep 16, 2019 · 14 comments
Closed

Deploying Thin Jars with Google App Engine Plugins #399

SudharakaP opened this issue Sep 16, 2019 · 14 comments

Comments

@SudharakaP
Copy link

It is stated in the documentation of GAE Java 11;

With a custom entrypoint, you can construct and package your application as a thin JAR file which only contains your application code and direct dependencies. When deploying your application, the App Engine plugin will only upload the files that changed, rather than the entire uber JAR package.

However it is unclear how to do this, as I've evidenced in this issue; jhipster/generator-jhipster#10362

Do you guys have an example or some information on how the thin jar should be build; should it be built with something like spring-boot-thin-launcher ? However this seems not to work since the thin jar will then try to download the dependencies and the GAE filesystem is readonly.

The approach we employed in the aforementioned issue is to extract the content of the fatjar within the staging directory; however with this approach; I am not sure of a easy method of removing the jar file (which then becomes useless) from the staging directory as appengine:deploy seems to both stage (again) and deploy the jar.

Maybe I am missing something here; so feel free to correct me if I am wrong. 😄

@loosebazooka
Copy link
Contributor

I don't think you should be extracting a fat jar.
You can build a regular jar, use the dependencies plugin to extract dependencies somewhere: http://maven.apache.org/plugins/maven-dependency-plugin/copy-dependencies-mojo.html

and then configure that target directory as an extra directory for the appengine application you're building, so your appengine-maven configuration will look something like:

<plugin>
  <artifactId>maven-dependency-plugin</artifactId>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>copy-dependencies</goal>
      </goals>
      <configuration>
        <outputDirectory>${project.build.directory}/dependencies</outputDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>
<plugin>
  <groupId>com.google.cloud.tools</groupId>
  <artifactId>appengine-maven-plugin</artifactId>
  <version>2.1.0</version>
  <configuration>
    <!--... whatever you have already ...-->
    <extraFilesDirectories>
       <extraFilesDirectory>${project.build.directory}/dependencies</extraFilesDirectory>
    </extraFilesDirectories>
  </configuration>
</plugin>

And when you run mvn package appengine:stage you should see what you want in the target directory.

Why can't you find <extraFilesDirectories> anywhere in the docs? It looks like we forgot to document it, I'll do that now.

@SudharakaP
Copy link
Author

SudharakaP commented Sep 16, 2019

@loosebazooka : I didn't know about the extraFilesDirectory; this is indeed the missing part. Wonderful; thanks much for your help. Let me change our integration to this method. 😄

@chanseokoh
Copy link
Contributor

chanseokoh commented Sep 16, 2019

If the app generated by JHipster is Spring Boot (I think it is), probably you need to adjust a few more things? Like making sure you're not including the fat JAR and having correct metadata (specifically the main method and classpath to those copied dependencies) in the thin JAR.

@SudharakaP
Copy link
Author

SudharakaP commented Sep 16, 2019

@chanseokoh : Wonderful. I looked at all sorts of different ways to do this; the main missing part is the <extraFilesDirectories> I think because I was thinking of a way to do exactly that.

If you guys could please, please do update the documents with more details about this; if you have a document repo; I am quite willing submit a pull request. There aren't any examples of doing this out there (at least I couldn't find any) so it's a bit hard. 😄

@loosebazooka
Copy link
Contributor

loosebazooka commented Sep 16, 2019

Yeah so #400 should have documentation for this. But we could probably also add a section in the FAQ about it.

@SudharakaP
Copy link
Author

SudharakaP commented Sep 16, 2019

@loosebazooka @chanseokoh : Just want to say thank you both of you for your very quick replies to our questions and adding it to the documentation 😄

On another note maybe if you could; I suggest also changing it here; https://cloud.google.com/appengine/docs/standard/java11/runtime#application_startup to elaborate more on what is meant by thin JAR as the description seems vague to me. Should it be built using spring boot tools like https://github.com/spring-projects-experimental/spring-boot-thin-launcher ; I now see it's not; it's just a regular jar. 😄

@loosebazooka
Copy link
Contributor

@SudharakaP That's a good suggestion, I'll bring it up with the docs team. Thanks!

@loosebazooka
Copy link
Contributor

So I've added faq entry for this repo: https://github.com/GoogleCloudPlatform/app-maven-plugin/blob/master/USER_GUIDE.md#how-do-i-deploy-a-thin-jar-to-app-engine

Going to close this for now.

@SudharakaP
Copy link
Author

@loosebazooka : Wonderful. Thanks a bunch. 😄

@SudharakaP
Copy link
Author

SudharakaP commented Sep 16, 2019

@loosebazooka : There's one question that is still pondering in my mind. So the extraFilesDirectories gets those extra directories and uploads them to staging? Are they handled separately. I mean if we upload all the dependencies anyways it's just kinda same as extracting a fatjar right? Say if I bump a version that will change the package contents in the extraFilesDirectories and then in the next appengine:deploy trigger it will not only update my pom file but also the bumped dependency within the extraFilesDirectories. Or am I missing something here? 😺

@loosebazooka
Copy link
Contributor

hrmm... I think you might have to do a mvn clean package appengine:deploy or something if the dependency versions change. OR something like this?
https://stackoverflow.com/questions/21566352/delete-old-artifact-version-before-copy-dependencies

@SudharakaP
Copy link
Author

SudharakaP commented Sep 16, 2019

@loosebazooka : Sorry I was confused a bit working on this problem for too long. I think I now see what you mean clearly. What you are essentially doing is separating the jar and it's dependencies. I once thought given the description at https://cloud.google.com/appengine/docs/standard/java11/runtime#application_startup that the app engine can handle actual "thin jars" where the app engine handles the downloading of dependencies. and we don't have to worry about any dependency copying or uploading whatsoever. What you are doing here (as well as what I have implemented at jhipster/generator-jhipster#10362) isn't too different from each other; only significant difference being since I didn't know about the extraFilesDirectories parameter and so I just dumped the dependencies to the appengine-staging directory before appengine:deploy runs. Also I lacked a workaround to remove the original jar file as suggested by ludoch.

Anyhow thanks for the clarifications. 😄

@alamothe
Copy link

alamothe commented Jul 7, 2020

Any example for Gradle?

@loosebazooka
Copy link
Contributor

@alamothe please take a look at the gradle plugin page: https://github.com/GoogleCloudPlatform/app-gradle-plugin and file an issue there with FULL details of your issue.

This issue is closed and should not be used to further discussion.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants