Revision history [back]

click to hide/show revision 1
initial version

answered 2020-07-28 12:08:50 +0800

cor3000 gravatar image cor3000

As you pointed out this doesn't happen in production, where a (re)deployed war file has a separate class loader - and ZK can initialize it's static members correctly.

What you didn't mention is the way/method you are starting your spring-boot application (so I am guessing you are using spring-boot-devtools as well). I could reproduce your exception adding spring-boot-devtools to the zkspringboot-demo-jar project

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <version>${springboot.version}</version>
    <optional>true</optional>
</dependency>

Then start it the Main class from the IDE, open http://localhost:8080/mvvm (which uses i18n labels).

Then change a java class -> recompile -> which triggers spring boot to reload the application, causing the error next time you access the same url.

During startup ZK assumes to be on a clean class loader (also in other places) so that I'd not try to change the ZK code.

Instead you can configure spring-boot-devtools accordingly to include the zk-jars during an application restart/reload.

Spring docs go quite into detail on how to use the devtools

In the restart-vs-reload section they mention 2 different class loaders which can be customized to include/exclude certain jar files (8.2.6).

Following the docs adding a spring-devtools.properties to include zk jars (brute force the ones starting with z*.jar) into the "restart"-classloader fixes the problem (might be fine tuned to only certain jars)

image description

As you pointed out this doesn't happen in production, where a (re)deployed war file has a separate class loader - and ZK can initialize it's static members correctly.

What you didn't mention is the way/method you are starting your spring-boot application (so I am guessing you are using spring-boot-devtools as well). I could reproduce your exception adding spring-boot-devtools to the zkspringboot-demo-jar project

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <version>${springboot.version}</version>
    <optional>true</optional>
</dependency>

Then start it the Main class from the IDE, open http://localhost:8080/mvvm (which uses i18n labels).

Then change a java class -> recompile -> which triggers spring boot to reload the application, causing the error next time you access the same url.

During startup ZK assumes to be on a clean class loader (also in other places) so that I'd not try to change the ZK code.

Instead you can configure spring-boot-devtools accordingly to include the zk-jars during an application restart/reload.

Spring docs go quite into detail on how to use the devtools

In the restart-vs-reload section they mention 2 different class loaders which can be customized to include/exclude certain jar files (8.2.6).

Following the docs adding a spring-devtools.properties to include zk jars (brute force the ones starting with z*.jar) into the "restart"-classloader fixes the problem (might be fine tuned to only certain jars)

image description

Besides that I personally don't like the devtools in this scenario, the benefits are marginal (the application still needs to restart - the start time is not reduced by a lot). It even restart the application too often for every css/js/zul/properties file change, when it's definitely not needed. ZK can reload those resources without restarting by simply disabling the caches as demonstrated in DevelopmentConfig.java. So many changes just get slower when restarting the application too eagerly.

Often the built-in hot code replacement is good enough when running in debug mode. And if needed a fresh start of the application is not much slower (maybe there are cases where the difference is significant which I haven't encountered so far).

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More