0

A very specific "Property not found" error

asked 2021-07-14 05:22:03 +0800

Jtt gravatar image Jtt
107 3

updated 2021-07-19 22:30:40 +0800

I'm currently modularizing a big chunk of code, and many of it is being put into separete VMs. So far, the last 4 submodules were easy: Take the code out, make the window, add the ViewModel attribute to the code and keep going.

But this time I'm being hit with the error in the title. I double checked that I had the variable, which is there, and triple checked the getter is there. Yet, I simply cannot use this new VM in the new window.

I decided, just to make sure I'm not overlooking something, to use ZK's @WireVariable instead of Spring's @Autowired. And yes: It worked. But why?

I've already checked the code and I can confirm that both the zul and my class are ok, but using a "component instead of a class" won't do for this specific window.

Just to be very sure I'm being understood:

I change

<div viewModel="@id('vm') @init(classComponent)">...</div>

to

<div viewModel="@id('vm') @init('whole.path.to.ClassComponent')">...</div>

also changing the appropiate binding from @Autowired to @WireVariable and magically(?) error's gone and component works.

I don't mind using ZK's bindings over Spring's, but most of out code uses Spring's and I'm pretty much cleaning code, so I'm trying to default to one notation.

In previews experiments I've found that all ViewModels I've worked on work with either 'style' so I'm positive they are pretty much interchangeable.

Not this window in particular, so... What could cause this? I have tried to replicate this error with no luck, and sadly I don't think I can reproduce it in a fiddle either. My best guess is that the zul page is being created before the getter in my component, which kind of breakes what I undesrtand of Spring.

Any idea will be much appreciated. Good day!

EDIT:

About said property:

The VM is a very simple class that loads text from our database into a popup window. It has only two properties (That we use in the front end): A list of Strings paragraphs and a String title. title gets initialized at @Init, and the whole error says "Property title not found in org.zkoss.zul.Window".

I was aware that I wasn't using the VariableResolver, but the last windows I've done don't use it. I thought "huh, weird but ok" when I noticed they all were properly working without it and moved on. This one seems to require it, altought I'm not 100% sure as of why. I guess I need to check in detail what is going on in these zk files. One of these windows doesn't actually use any variables (It's all GUI and commands with no inputs or reads from the backend) so that one should be fine even without the VariableResolver as far as I understand, but the others I'm not so sure.

Again, I'm not really concerned. If they work they work and optimizing them isn't really my requirement but I'd like to document this behaviour in simple spanish for newer front ends that might come in the future.

I'll experiment some more and if the seniors don't like me mixing @Autowire and @WireVariable, I'll add the VariableResolver.

EDIT:

These are code snippets that represent my .zul file:

<zk>
    <window viewModel="@id('vm') @init(documentWindow)">
        <caption/>
        <div>
            <div class="document-title">
                <label id="docTitle" value="@load(vm.documentTitle)"/>
            </div>
            <div class="document-paragraph" children="@load(vm.documentParagraphs)">
                <template name="children" var="p">
                    <span>${p.text}</span>
                </template>
            </div>
        </div>
    </window>
</zk>

and my ViewModel:

@Component
public class DocumentWindow {

    @Autowired
    private ParagraphsRepository paragraphsRepository;

    private String documentTitle; // this is the property that is "not found"
    private List<Paragraphs> documentParagraphs;

    @Init
    public void init(@ExecutionArgParam("id") Integer docId, @ExecutionArgParam("docTitle") String documentTitle) {
        this.documentTitle = documentTitle;
        this.documentParagraphs = paragraphsRepository.findRelevantByDocId(docId);
    }

    public String getDocumentTitle() {
        return this.documentTitle;
    }

    public List<Paragraphs> getDocumentParagraphs() {
        return this.documentParagraphs;
    }

}

There is more going on both files, but the error refers especifically to documentTitle, so I used only the relevant code. Using this "template" so to speak, it throws the "Property not found" error, targeting documentTitle as the property and org.zkoss.zul.Window as the class it's missing from. If I change the way I bind the VM and use the whole class name (Changing to @WireVariable), the code works as expected. I'm aware of the lack of a VariableResolver, but again I've use this exact same "template" with other windows and components without an issue.

This window is being created from another viewModel(s) using Executions.createComponent() where I pass the parameters. So far, the only "logical" thing I have though might have happened is that the zul page loaded faster than the call to the bean. This because when setting a breakpoint at the first line of the @Init method in debug, it throws the error before going into the VM. But that is a bit of a wild guess on my part. This doesn't explain why my few other popup windows work just fine with this "tempalte" with no VariableResolver though.

Good day!

delete flag offensive retag edit

3 Answers

Sort by ยป oldest newest most voted
0

answered 2021-07-14 10:43:19 +0800

hawk gravatar image hawk
2849 1 5
http://hawkphoenix.blogsp... ZK Team

Thanks for your writing in patient. But you don't mention which property is not found. Is that property a spring bean? Based on your story, I still cannot image the whole picture. So I just give you my inference.

If you write this

<div viewModel="@id('vm') @init(classComponent)">...</div>

ZK will treat classComponent as a variable name and resolve this variable as a key in scope attributes from small scope to larger one:

  1. execution
  2. component
  3. page
  4. desktop
  5. session
  6. application

If the variable is a spring bean, you should add the resolver below, then zk can resolve it as a spring bean whose bean name is the variable name:

<?variable-resolver class="org.zkoss.spring.DelegatingVariableResolver"?>

If the ViewModel is a spring bean, then Spring @AutoWired in the ViewModel can work correctly because Spring instantiate this ViewModel, spring can do the dependency injection.

If you write a full-qualified class name like:

<div viewModel="@id('vm') @init('whole.path.to.ClassComponent')">...

Then ZK will instantiate the class, so the ViewModel is not a spring bean. Therefore, Spring @AutoWired doesn't work in the ViewModel. Only ZK's @WireVairable can work. If you want to wire a spring-managed bean, you need a add a resolver in ViewModel:

@VariableResolver(org.zkoss.zkplus.spring.DelegatingVariableResolver.class)
link publish delete flag offensive edit

Comments

Thanks for your reply! You're right, I forgot to add details on the property. For short, is a String being called after a dynamic list, which is weird: The dynamic list doesn't throw the error (It should since it's loaded earlier, right?) I'll edit my question.

Jtt ( 2021-07-14 21:53:24 +0800 )edit
0

answered 2021-07-15 14:21:23 +0800

hawk gravatar image hawk
2849 1 5
http://hawkphoenix.blogsp... ZK Team

Property title not found in org.zkoss.zul.Window

This error message is quite unexpected to me because Window does have a property title. So I wonder what's the complete stack trace.

case 1. If you set a non-existed attribute on window like:

<window noattribute="a"/>

you will get

org.zkoss.zk.ui.metainfo.PropertyNotFoundException: Method setNoattribute not found for class org.zkoss.zul.Window

case 2. If you bind a non-existed property from a vm, you will get

org.zkoss.zel.PropertyNotFoundException: Property 'abc' not found on type issue.ListGroupVM

According to your error message, it looks like case 2. but we usually don't use ZK component class as a ViewModel.

link publish delete flag offensive edit

Comments

Yes, it is case 2. To clarify, the property "title" I refer to is independent of Window's title. This window displays part of a document so I also need a title haha. Just for good measure change the name of this variable, but the exception persists.

Jtt ( 2021-07-15 21:59:41 +0800 )edit
0

answered 2021-07-19 10:23:19 +0800

hawk gravatar image hawk
2849 1 5
http://hawkphoenix.blogsp... ZK Team

I'm quite confused with your case. The case2. means bind a non-existed property of a ViewModel. Do you mean you use a org.zkoss.zul.Window as a ViewModel? If so, that's an invalid usage. When using Data binding, you should bind a ViewModel's property (POJO) to a component's attribute.

link publish delete flag offensive edit

Comments

Apologies. I'm not being clear enough. I'll add an example that visually represents the case. Short answer to your answer: I'm not using o.z.z.Window as a ViewModel nor inheriting from it.

Jtt ( 2021-07-19 21:52:49 +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
1 follower

RSS

Stats

Asked: 2021-07-14 05:22:03 +0800

Seen: 19 times

Last updated: Jul 19

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