paketo-buildpacks / executable-jar

A Cloud Native Buildpack that contributes a Process Type for executable JARs.
Apache License 2.0
15 stars 7 forks source link

watchexec not work for java -jar #164

Open zhoufenqin opened 2 years ago

zhoufenqin commented 2 years ago

I config BP_LIVE_RELOAD_ENABLED env to enable live process reloading, then create a Procfile to determine my process type. After that, deploy the app to k8s

Procfile:

web: watchexec -r --shell=none -- java -jar /byos/1019/echo-app-mason-with-log4j-0.0.1-SNAPSHOT.jar

Build logs

Paketo Buildpack for Procfile 5.4.0
  https://github.com/paketo-buildpacks/procfile
  Process types:
    web: watchexec -r --shell=none -- java -jar /byos/1019/echo-app-mason-with-log4j-0.0.1-SNAPSHOT.jar

exec to pod, shows process:

cnb@app-newre-default-9-d5f5844c4-wmd7z:/byos/1019$ ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
cnb          1     0  0 07:25 ?        00:00:00 watchexec -r --shell=none -- java -jar /byos/1019/echo-app-mason-with-log4j-0.0.1-SNAPSHOT
cnb        101     1  1 07:25 ?        00:00:32 java -jar /byos/1019/echo-app-mason-with-log4j-0.0.1-SNAPSHOT.jar
cnb        225     0  0 07:38 pts/0    00:00:00 bash

Then I change my jar file and update some files, then the container doesn't restart. but the jar file has already been updated.

image

Another question

If I deploy the sprint boot project to a cloud platform, like azure, what's the usage to watch a workspace? E.g If I watch a sprint boot project

 watchexec -r --shell=none -- java org.springframework.boot.loader.JarLauncher

the workspace is default /workspace,

cnb@app-dynamic-default-11-96d7c598-zdzld:/workspace$ ls
BOOT-INF  META-INF  org

I can't update the class file in the /workspace directly, so what's the meaning of watching this?

Expected Behavior

the jar file update should be detected and restart the container

Current Behavior

the jar file changed but the container is not restarted

Possible Solution

Steps to Reproduce

1.

Motivations

dmikusa commented 2 years ago

then create a Procfile to determine my process type

This is unnecessary. The Java buildpacks will determine the correct process type, even with reloading enabled. The process type will be called reload.

Then I change my jar file and update some files,

How are you doing this specifically? Are you using Tilt, or some other way to reload them?

Then I change my jar file and update some files, then the container doesn't restart. but the jar file has already been updated.

Usually, when you deploy with buildpacks, it explodes your JAR file and runs from disk. This works much better when using watchexec because individual files can be updated. This works great with Tilt and your IDE so you can save and automatically have changes pushed to your container.

If your build results in a JAR file, then you have to update the entire JAR file every time you want the process to reload, which is less convenient.

If I deploy the sprint boot project to a cloud platform, like azure, what's the usage to watch a workspace?

Check out this: https://paketo.io/docs/howto/java/#using-tilt-with-paketo-buildpacks

zhoufenqin commented 2 years ago

Hi @dmikusa, I just want to test watchexec so I use a Procfile and package a jar file to check if I change the jar file, whether the watchexec can detect it or not.

How are you doing this specifically? Are you using Tilt, or some other way to reload them?

No, I mount a file to a pod and package the jar file locally, then upload it to the cloud storage, then the file in the mount path will be updated. Although it's less convenient, the watchexec should detect the jar file change. but I didn't see the container reload. (PS, I only change some content in a java class file, I think it can be detected because the .class file is changed)

Check out this: https://paketo.io/docs/howto/java/#using-tilt-with-paketo-buildpacks

If customers deploy apps in the cloud platform, like Azure Spring Apps, then maybe customers can't see the backend pods in k8s, In such case, I think a tool like tilt is not very useful. But if customers manage their own k8s, then tools like tilt is useful, is it right? Besides, in JAVA, spring hot reload or Plugin like JRebel can also watch changes, is watchexec a general solution to watch file changes? polyglot apps all can use the watchexec buildpack

dmikusa commented 2 years ago

No, I mount a file to a pod and package the jar file locally, then upload it to the cloud storage, then the file in the mount path will be updated. Although it's less convenient, the watchexec should detect the jar file change. but I didn't see the container reload. (PS, I only change some content in a java class file, I think it can be detected because the .class file is changed)

I don't know exactly what watchexec is doing to check for modified files, but I believe it's using OS-level features to be notified when files have changes. I really can't say how well watchexec would work with a cloud-storage backed file system or volume mount.

What I can say is that when watchexec notices a change it will not restart the container. It will reload the process in the container. When watchexec is enabled, it runs as the parent process and spawns your application as a child process. When it detects a changed file, it'll kill your process & spawn a new process. That means you can tell if it's picking up file changes by looking to see if the pid of your application process in the container changes. You can also look at the logs, you should see the JVM & Spring Boot restart when your app restarts, so there will be new log entries when that happens.

If customers deploy apps in the cloud platform, like Azure Spring Apps, then maybe customers can't see the backend pods in k8s, In such case, I think a tool like tilt is not very useful. But if customers manage their own k8s, then tools like tilt is useful, is it right?

This is getting out of my area of expertise, but I believe Tilt has to have access to the K8s API to deploy the pod where your app runs.

Besides, in JAVA, spring hot reload or Plugin like JRebel can also watch changes, is watchexec a general solution to watch file changes? polyglot apps all can use the watchexec buildpack

Yes, watchexec is a general solution. It watches for file changes and reloads the whole process. We started with this in buildpacks because it's very simple to implement. The performance for most microservice-style apps isn't going to be that bad. Even if it takes 1-2 seconds to restart your app, by the time you save in your IDE, switch to the browser, and hit refresh, it's likely to have restarted.

We'd originally talked about integrating with Spring Boot Dev Tools and we still might, but I think we're just waiting to see how much use folks get out of this type of setup and if it's worth the extra effort to utilize a tool like that.

If anyone is interested in contributing a PR for Spring Boot Dev Tools support that would be fantastic & I'd be happy to talk through that.