0

ZK9 internationalization java.lang.IllegalStateException

asked 2020-02-12 08:41:59 +0800

sa3a78 gravatar image sa3a78
30

I have issue when using internationalization. I'm using Netbeans8.2 with Tomcat9. I have tried the expression ${labels.login.label.title}, ${c:l('login.label.title')}, and Labels.getLabel("login.label.title"), they show error as below:

Exception

java.lang.IllegalStateException: The resources may not be accessed if they are not currently started
    org.apache.catalina.webresources.StandardRoot.validate(StandardRoot.java:247)
    org.apache.catalina.webresources.StandardRoot.getResource(StandardRoot.java:213)
    org.apache.catalina.webresources.StandardRoot.getResource(StandardRoot.java:207)
    org.zkoss.web.util.resource.ServletLabelLocator.locate0(ServletLabelLocator.java:94)
    org.zkoss.web.util.resource.ServletLabelLocator.locate(ServletLabelLocator.java:77)
    org.zkoss.util.resource.impl.LabelLoaderImpl.loadLabels(LabelLoaderImpl.java:272)
    org.zkoss.util.resource.impl.LabelLoaderImpl.getLabel(LabelLoaderImpl.java:130)
    org.zkoss.util.resource.impl.LabelLoaderImpl.getLabel(LabelLoaderImpl.java:121)
    org.zkoss.util.resource.Labels.getLabel(Labels.java:61)
    org.zkoss.xel.fn.CommonFns.getLabel(CommonFns.java:134) 
        .....



zk.xml

<system-config>
   <label-location>/WEB-INF/labels/baseapp.properties</label-location>
</system-config>


baseapp.properties

login.label.title=Form Login
login.label.username=Username
login.label.password=Password
login.label.login=Login
login.msg.logout=Confirm Logout ?
login.error.emptydata=invalid data: username or password empty
login.error.notexist=username not exist or wrong password
delete flag offensive retag edit

3 Answers

Sort by ยป oldest newest most voted
1

answered 2020-02-12 15:01:22 +0800

MDuchemin gravatar image MDuchemin
2560 1 6
ZK Team

Hi there,

Does this always happen when you load the page? Or is it a "sometime" issue?

Does this only happen when you run the project from Netbeans in the tomcat container? If you package the project as a war file and deploy it to tomcat manually, do you get the same error?

It looks like this issue could be caused by the webapp trying to access some resources while still redeploying / restarting the container. If you have auto-deploy on change, it would be possible that the app tried to access some resource while being restarted / redeployed.

link publish delete flag offensive edit
0

answered 2020-07-24 22:50:41 +0800

54patman gravatar image 54patman
13 3

updated 2020-07-25 05:41:11 +0800

This never appears in production because the server is always restarted. I'm using 9.0.1

I have the same issue (maybe bug) and it's only during development and when the spring boot internal tomcat restarts due to a code/file change.

Basically I hunted the issues down: ZkAutoConfiguration.httpSessionListener()

Has a HttpSessionListener anonymous class where the line: webManager = new WebManager(ctx, zkProperties.getUpdateUri());

is called when the servelet context is reloaded without a server restart.

Eventually in the constructor of WebManager you get to this block:

String[] labellocs = config.getLabelLocations();

if (labellocs.length == 0)

   Labels.register(new ServletLabelLocator(_ctx));

which will register the new label location, the problem is the old stale one was not cleared.

So when the label tries to resolve and load the properties files it first finds the old stale ServletLabelLocator as it saved in a LinkedHashSet. Then tries to load but because the context is closed and unavailable it throws an exception.

see in LabelLoaderImpl: private final Set _locators = new LinkedHashSet(4); //order is important

Basically the fix is to clear the _locators of LabelLoaderImpl when constructing the WebManager object.

Something like:

String[] labellocs = config.getLabelLocations();

//*******new code, bug fix for context restarts and labels

Labels.clearRegisters();//but method does not exist!

//************************

if (labellocs.length == 0)

    Labels.register(new ServletLabelLocator(_ctx));

I'm seeing if I can do this but it's not easy as the code is deep in zk and I'm not sure how to override or overload these classes.

link publish delete flag offensive edit
0

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

cor3000 gravatar image cor3000
6280 2 7

updated 2020-07-28 12:17:06 +0800

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).

link publish delete flag offensive edit

Comments

just noticed 8.2.2 excluding resources

In a ZK application with caches disabled this mostly matches any resource below /web/**

cor3000 ( 2020-07-28 12:24:46 +0800 )edit
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow
2 followers

RSS

Stats

Asked: 2020-02-12 08:41:59 +0800

Seen: 22 times

Last updated: Jul 28 '20

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