How to reference an included zul file in customization bundle when performing Executions.createComponents

934 views
Skip to first unread message

Kevin Yang

unread,
Nov 17, 2013, 1:55:21 AM11/17/13
to idem...@googlegroups.com
Hi All,

Thank you very much for review my topic.

I created a normal bundle as Plug-in project, and I created an zul file "zulFileName.zul" in path "/zul",

When I tried to call  Executions.createComponents("/zul/ZMRPDetailed.zul", null, null) to create the component, error message out:

Nov 17, 2013 2:21:05 PM org.zkoss.zk.ui.impl.UiEngineImpl handleError:1359
SEVERE: >>org.zkoss.zk.ui.UiException: Page not found: /zul/zulFileName.zul
>> at org.zkoss.zk.ui.http.ExecutionImpl.getPageDefinition(ExecutionImpl.java:371)
>> at org.zkoss.zk.ui.impl.AbstractExecution.createComponents0(AbstractExecution.java:246)
>> at org.zkoss.zk.ui.impl.AbstractExecution.createComponents(AbstractExecution.java:238)
>> at org.zkoss.zk.ui.Executions.createComponents(Executions.java:179)

But If I change the current bundle to fragment against org.adempiere.ui.zk(Host), Executions.createComponents("/zul/ZMRPDetailed.zul", null, null) will create the component.

If you know the reason, Would you please tell me why I can't use Executions.createComponents("/zul/ZMRPDetailed.zul", null, null)  in normal bundle.

If I want to use zul files to develop some UI forms to extension ID's webUI in my customization bundle(not fragment), What need I do?

Thanks again.

Best Regards,
Kevin

Heng Sin Low

unread,
Nov 17, 2013, 9:54:50 AM11/17/13
to idem...@googlegroups.com
You have 2 options here:
1) Use Executions.createComponents(url, parent, arg) and you have to host all your plugin's zul resources as fragment. i.e you have a plugin to host your code plus a fragment projects to host your zul resources.

2) Have a single plugin projects to host your code + zul resources. For this setup, you need to use one of the Executions.createComponentsDirectly method instead. To access your plugin's zul resource as uri, use the bundleContext.getBundle().getEntry(path) method.

--
You received this message because you are subscribed to the Google Groups "iDempiere" group.
To unsubscribe from this group and stop receiving emails from it, send an email to idempiere+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Kevin Yang

unread,
Nov 17, 2013, 11:33:21 AM11/17/13
to idem...@googlegroups.com
Hi Hengsin,

Thank you very much for your reply.

Now I am using option 1 to solve this issue. But in fact, I prefer the option 2.
I use a normal JavaObject(implements from IFormFactory) to create the components, So I use the below code instead of "bundleContext.getBundle().getEntry(path)"

"URL zulFileUrl =this.getClass().getClassLoader().getResource(zulfile);"  to get the URI. When I call 
"
reader = new BufferedReader(new InputStreamReader(zulFileUrl.openStream()));
page = (ADForm) Executions.createComponentsDirectly(reader, null, null, null);
"
the zul file can be load, but the apply class(org.test.erp.mfg.controller.MRPDetailedController) in zul file will through ClassNotFoundException exception as 

Nov 18, 2013 12:27:34 AM org.zkoss.zk.ui.impl.UiEngineImpl handleError:1359
SEVERE: >>org.adempiere.webui.exception.ApplicationException: java.lang.ClassNotFoundException: org.test.erp.mfg.controller.MRPDetailedController
>>org.zkoss.zk.ui.UiException: java.lang.ClassNotFoundException: org.test.erp.mfg.controller.MRPDetailedController
>>java.lang.ClassNotFoundException: org.test.erp.mfg.controller.MRPDetailedController
>> at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:513)
>> at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:429)
>> at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:417)
>> at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
>> at java.lang.ClassLoader.loadClass(Unknown Source)
>> at java.lang.Class.forName0(Native Method)
>> at java.lang.Class.forName(Unknown Source)
>> at org.zkoss.lang.Classes.forNameByThread(Classes.java:271)
>> at org.zkoss.lang.ImportedClassResolver.resolveClass(ImportedClassResolver.java:122)
>> at org.zkoss.zk.ui.impl.PageImpl.resolveClass(PageImpl.java:478)
>> at org.zkoss.zk.ui.impl.AbstractUiFactory.newComposer(AbstractUiFactory.java:142)
>> at org.zkoss.zk.ui.impl.Utils.newComposer(Utils.java:89)
>> at org.zkoss.zk.ui.metainfo.ComponentInfo.toComposer(ComponentInfo.java:355)
>> at org.zkoss.zk.ui.metainfo.ComponentInfo.toComposers(ComponentInfo.java:323)
>> at org.zkoss.zk.ui.metainfo.ComponentInfo.resolveComposer(ComponentInfo.java:310)
>> at org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild0(UiEngineImpl.java:786)
>> at org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild(UiEngineImpl.java:778)
>> at org.zkoss.zk.ui.impl.UiEngineImpl.execCreate0(UiEngineImpl.java:687)
>> at org.zkoss.zk.ui.impl.UiEngineImpl.execCreate(UiEngineImpl.java:651)
>> at org.zkoss.zk.ui.impl.UiEngineImpl.createComponents(UiEngineImpl.java:1032)
>> at org.zkoss.zk.ui.impl.AbstractExecution.createComponentsDirectly0(AbstractExecution.java:312)
>> at org.zkoss.zk.ui.impl.AbstractExecution.createComponentsDirectly(AbstractExecution.java:302)
>> at org.zkoss.zk.ui.Executions.createComponentsDirectly(Executions.java:290)

Heng Sin Low

unread,
Nov 17, 2013, 1:11:24 PM11/17/13
to idem...@googlegroups.com
Try setting this.getClass().getClassLoader() as the current thread's context class loader.

Kevin Yang

unread,
Nov 19, 2013, 2:08:44 AM11/19/13
to idem...@googlegroups.com
Hi Hengsin,

I have tried

URL zulFileUrl =this.getClass().getResource(zulfile);

But zulFileUrl Object return null. 
I am still not so clear about "set this.getClass().getClassLoader() as the current thread's context class loader." 
Would you please give me some tips?

Thank you very much,
Best Regards,
Kevin

Heng Sin Low

unread,
Nov 19, 2013, 7:53:14 AM11/19/13
to idem...@googlegroups.com
I means call Thread.currentThread.setContextClassLoader((this.getClass().getClassLoader()) before the call to Executions.createComponentsDirectly.

For access to bundle context, you need to create a Activator object for your plugin and cache the bundlecontext as static variable in the start method ( for e.g, see org.adempiere.base.BaseActivator ).

Kevin Yang

unread,
Nov 19, 2013, 9:03:55 AM11/19/13
to idem...@googlegroups.com
Hi Hengsin,

Thank you very much.
The issue is resolved after I called Thread.currentThread.setContextClassLoader((this.getClass().getClassLoader()) .

Best Regards,
Kevin
Reply all
Reply to author
Forward
0 new messages