History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: XW-493
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Rainer Hermanns
Reporter: Jasper Rosenberg
Votes: 2
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
XWork

Packages in includes can't see packages declared ahead of include

Created: 14/Mar/07 09:40 AM   Updated: 11/Apr/07 11:36 AM
Component/s: Configuration
Affects Version/s: 2.0.1
Fix Version/s: 2.0.2, 2.1

File Attachments: 1. Text File XmlConfigurationProvider.patch (5 kb)
2. Text File XW493.patch (16 kb)

Issue Links:
Related
This issue relates to:
XW-486 Error dealing with includes in XmlCon... Major Resolved
 

Flags: Important, Patch


 Description  « Hide
In reference to: http://forums.opensymphony.com/thread.jspa?threadID=70440&tstart=0

Basically, a package in an included file can't see packages declared in the file which included it.

This is because a file's packages are now processed file depth first (rather than absolute order as if all files were flattened together).

Unfortunately, the fix I suggest in that thread won't actually work because there might be packages after the includes that depend on packages in the includes.

This did used to work (in XWork 1), and one can see why that might have been the case as the packages and includes used to be processed interwined in com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadConfigurationFiles() (You can see where the addPackage() call has been commented out).

 All   Comments   Change History      Sort Order:
Rainer Hermanns - [04/Apr/07 01:55 PM ]
I am working on this issue now...
I have a unit test showing the problem, but it will take a couple of hours, since my time is limited...
The whole configuration loading needs to be reworked, if I got it right.

You do not have a patch arround to solve this issue? :)

cheers,
Rainer

Jasper Rosenberg - [04/Apr/07 02:36 PM ]
Ugh, wish I had a patch for ya. If it helps, it works correctly in the latest XWork 1, so perhaps you can go back through the history and identify what/why it was changed...

Rainer Hermanns - [05/Apr/07 07:22 AM ]
This is a patch proposal for this and the linked issue.

As you can see, the failing package configurations are stored in a temporary list.
The failure list is recursively processed after the initial configuration has been loaded...
This should solve the above issue.

Jasper, could you please apply the patch and see if this works for you?

tia,
Rainer

Jasper Rosenberg - [05/Apr/07 08:31 AM ]
Hi Rainer,

I'm afraid that I am out until next Wed. There seem to be lots of interested parties to this issue though (given all the related issues in struts 2), so you might want to see if you can get someone else to check out the patch if you want an quicker review. It does sound like a clever solution though and, based on your description, will have the nice side-effect of having package order no longer matter at all (whereas in XWork 1 the package order did have to be sequential if you imagined flattening all the imported files.)

-Jasper

Rainer Hermanns - [05/Apr/07 09:43 AM ]
Fixed in SVN for 2.0.2/2.1

Jasper Rosenberg - [11/Apr/07 10:53 AM ]
Hi Rainer,

The patch looks like it will work, but I do have some suggestions for improvement (this is by inspection rather than execution, so hopefully I didn't misread the code):

  1. In XmlConfigurationProvider.loadPackages(), the reloads.clear() call is unnecessary.

  2. In XmlConfigurationProvider.reloadRequiredPackages(), I think that you want to return directly after the recursive call, otherwise you will get logging errors for packages that were actually resolved in the recursive invocation.

  3. If I understand the current flow correctly, it will end up reprocessing all packages in a document that might only have a subset of packages that had parents that were not yet declared. In fact, because a doc gets processed for every package where we can't find a parent, the same package could end up processed many times over.

For example, a single document with packages declared in the following order:
package C extends B
package B extends A
package A

i. C, B, and A are processed, C and B are to be reloaded, A is successfully added.
ii. C's doc is processed, so C, B, and A are all processed again, C is added to "result" to be reloaded recursively, B is successfully added, A is overwritten.
iii. B's doc is processed, so C, B, and A are all processed again, C is successfully added, A and B are overwritten.
iv. C's doc is processed again (from recursive call), so C, B, and A are all processed again and A, B, and C are overwritten.

Ideally, this could be avoided by reloading the children packages directly rather than reprocessing their entire parent document for each package whose parent was not found. The one complication to this is the loadExtraConfiguration(doc) call which I'm not sure belongs conceptually in reloadRequiredPackages() anyway. Should it be allowed to be called multiple times per document? Also, does it need to be called in document load order? Perhaps it should be factored out to its own loop to be called a single time on each document after the call to reloadRequiredPackages() in loadPackages().

Hope something in here is helpful!

-Jasper

Rainer Hermanns - [11/Apr/07 11:12 AM ]
Jasper,

thanks for your comments.

1) true, just helping the garbage collector here :)
2) This one is already resolved. The patch has been improved and already commited. So the logging should only apply, when the package could not be loaded at all.
3) For clarification, an already processed package will not be processed again. Therefore I added the "needsRefresh" boolean property to PackageConfig.
Only "dirty" packages will be checked and if possible initialized. Only the document is reparsed several times...
Regarding the loadExtraConfiguration, this sounds reasonable to me, but I won't have time to look into this before next weekend.
If you could provide a patch with your suggestion I'd be happy to apply it.

tia,
Rainer

Jasper Rosenberg - [11/Apr/07 11:27 AM ]
Hi Rainer,

Here is a patch that includes all of my suggested changes. It is against the trunk. Processing at the package level rather than the doc level greatly simplified things...

Thanks,
Jasper

Jasper Rosenberg - [11/Apr/07 11:36 AM ]
Oh also, I did rerun your new unit test against my patch.

Regarding your responses:

1) true, just helping the garbage collector here :)

I suppose technically the garbage collector could run in the half a ms before it goes out of scope on its own ;)

2) This one is already resolved. The patch has been improved and already commited. So the logging should only apply, when the package could not be loaded at all.

I'm not seeing this in svn, perhaps there is some lag, but in any case it is handled by my patch as well.

3) For clarification, an already processed package will not be processed again. Therefore I added the "needsRefresh" boolean property to PackageConfig.
Only "dirty" packages will be checked and if possible initialized. Only the document is reparsed several times...

I guess I would need to step through the code to be sure, but looking at addPackage(), I'm not seeing anywhere where it recognizes that a package was previously parsed. It just looks to me like it will be reprocessed and then overwrite the earlier one... I guess I must be missing something...