问题
This is a continuation of a question that I asked last week.
With the answers I received, I was able to set up an environment where I could, at least theoretically start working to copy my classes into a plug-in project from designer.
Currently, I have imported the ExtLibs source as projects (other than a few test projects which hopefully do not matter) without any errors, the openNTF Domino API, and a plug-in project for my utility files. I configured my debug options, and have tried to get this to run on the server. I think I have been successful.
(Server and Client both are on the same local machine. The client, that I use for all other development as well, already have ExtLibs, opentNTF Domino API, and openLog features installed from update sites.)
I can verify that those features are installed on the server via eclipse by running the following console commands:
tell http osgi ss com.ibm.xsp.extlib
[196C:0002-1F7C] 23.06.2014 15:51:42 Framework is launched.
[196C:0002-1F7C] 23.06.2014 15:51:42 id State Bundle
[196C:0002-1F7C] 23.06.2014 15:51:42 97 RESOLVED com.ibm.xsp.extlibx.oauth_9.0.1.v00_06_qualifier
[196C:0002-1F7C] 23.06.2014 15:51:42 Master=113
[196C:0002-1F7C] 23.06.2014 15:51:42 102 ACTIVE com.ibm.xsp.extlib.core_9.0.1.v00_06_qualifier
[196C:0002-1F7C] 23.06.2014 15:51:42 103 ACTIVE com.ibm.xsp.extlib.domino_9.0.1.v00_06_qualifier
[196C:0002-1F7C] 23.06.2014 15:51:42 104 ACTIVE com.ibm.xsp.extlib.controls_9.0.1.v00_06_qualifier
[196C:0002-1F7C] 23.06.2014 15:51:42 108 RESOLVED com.ibm.xsp.extlibx.controls_9.0.1.v00_06_qualifier
[196C:0002-1F7C] 23.06.2014 15:51:42 109 ACTIVE com.ibm.xsp.extlibx_9.0.1.v00_06_qualifier
[196C:0002-1F7C] 23.06.2014 15:51:42 112 ACTIVE com.ibm.xsp.extlib.mobile_9.0.1.v00_06_qualifier
[196C:0002-1F7C] 23.06.2014 15:51:42 113 ACTIVE com.ibm.xsp.extlib_9.0.1.v00_06_qualifier
[196C:0002-1F7C] 23.06.2014 15:51:42 Fragments=97
[196C:0002-1F7C] 23.06.2014 15:51:42 115 ACTIVE com.ibm.xsp.extlib.oneui_9.0.1.v00_06_qualifier
[196C:0002-1F7C] 23.06.2014 15:51:42 116 <<LAZY>> com.ibm.xsp.extlibx.core_9.0.1.v00_06_qualifier
[196C:0002-1F7C] 23.06.2014 15:51:42 118 ACTIVE com.ibm.xsp.extlibx.relational_9.0.1.v00_06_qualifier
tell http osgi ss org.openntf.domino.xsp.XspLibrary
[196C:0002-1F7C] 23.06.2014 15:52:32 Framework is launched.
[196C:0002-1F7C] 23.06.2014 15:52:32 id State Bundle
and my new project - tell http osgi ss de.holistic.utils
[196C:0002-1F7C] 23.06.2014 15:53:24 Framework is launched.
[196C:0002-1F7C] 23.06.2014 15:53:24 id State Bundle
[196C:0002-1F7C] 23.06.2014 15:53:24 100 INSTALLED de.holistic.utils_1.0.0.qualifier
I then try to use my new plug-in in a project. (The project is actually a copy of my original development .nsf where I have a few test XPages. I have removed the old src folder from the build path in order to prove that I am indeed using the code developed on the server. The faces-config.xml file has not been changed, and the beans that used to serve as entry points to my utilities really are not pointing to any classes that can be found on the local designer installation. (Runtime/Build errors) Of course this cannot work even if the server will know what the classes are. The designer client which is building the application has no idea what I am trying to do.
Questions
- How might I best go about using a plug-in for testing in a designer client? Must I export the plug-in into an update site every time I test a change and install it as a widget like I do for ExtLib installation? That seems rather inefficient as opposed to the server tests.
- Since my current errors are coming from the faces-config.xml, my first thought is to take my variable names / bean names out of the file, and register them somehow to the runtime. My first thought is to somehow register them with faces in the activator class, but I am unsure. How might I best go about doing that?
As always, I am very grateful for all help given. Coming from LotusScript, I do not have much experience with this new JSF/OSGi stuff, but am pretty impressed!
designer installation stack trace
Unable to read variable and containers file
java.io.EOFException
at java.io.DataInputStream.readInt(Unknown Source)
at org.eclipse.wst.jsdt.internal.core.JavaModelManager$VariablesAndContainersLoadHelper.loadInt(Unknown Source)
at org.eclipse.wst.jsdt.internal.core.JavaModelManager$VariablesAndContainersLoadHelper.loadVariables(Unknown Source)
at org.eclipse.wst.jsdt.internal.core.JavaModelManager$VariablesAndContainersLoadHelper.load(Unknown Source)
at org.eclipse.wst.jsdt.internal.core.JavaModelManager.loadVariablesAndContainers(Unknown Source)
at org.eclipse.wst.jsdt.internal.core.JavaModelManager.startup(Unknown Source)
at org.eclipse.wst.jsdt.core.JavaScriptCore.start(Unknown Source)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Unknown Source)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(Unknown Source)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(Unknown Source)
at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(Unknown Source)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(Unknown Source)
at org.eclipse.osgi.framework.util.SecureAction.start(Unknown Source)
at org.eclipse.core.runtime.internal.adaptor.EclipseLazyStarter.postFindLocalClass(Unknown Source)
at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass(Unknown Source)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLocalClass(Unknown Source)
at org.eclipse.osgi.framework.internal.core.BundleLoader.findLocalClass(Unknown Source)
at org.eclipse.osgi.framework.internal.core.BundleLoader.findClassInternal(Unknown Source)
at org.eclipse.osgi.framework.internal.core.BundleLoader.findClass(Unknown Source)
at org.eclipse.osgi.framework.internal.core.BundleLoader.findClass(Unknown Source)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.eclipse.osgi.framework.internal.core.BundleLoader.loadClass(Unknown Source)
at org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(Unknown Source)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(Unknown Source)
at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(Unknown Source)
at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(Unknown Source)
at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(Unknown Source)
at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(Unknown Source)
at org.eclipse.core.internal.preferences.PreferenceServiceRegistryHelper.runInitializer(Unknown Source)
at org.eclipse.core.internal.preferences.PreferenceServiceRegistryHelper.applyRuntimeDefaults(Unknown Source)
at org.eclipse.core.internal.preferences.PreferencesService.applyRuntimeDefaults(Unknown Source)
at org.eclipse.core.internal.preferences.DefaultPreferences.applyRuntimeDefaults(Unknown Source)
at org.eclipse.core.internal.preferences.DefaultPreferences.loadDefaults(Unknown Source)
at org.eclipse.core.internal.preferences.DefaultPreferences.load(Unknown Source)
at org.eclipse.core.internal.preferences.EclipsePreferences.create(Unknown Source)
at org.eclipse.core.internal.preferences.EclipsePreferences.internalNode(Unknown Source)
at org.eclipse.core.internal.preferences.EclipsePreferences.node(Unknown Source)
at org.eclipse.core.internal.preferences.AbstractScope.getNode(Unknown Source)
at org.eclipse.core.runtime.preferences.DefaultScope.getNode(Unknown Source)
at com.ibm.designer.domino.rcp.personality.DesignerWorkbenchWindowAdvisor.setJavaCompilerSettings(Unknown Source)
at com.ibm.designer.domino.rcp.personality.DesignerWorkbenchWindowAdvisor.postWindowCreate(Unknown Source)
at org.eclipse.ui.internal.WorkbenchWindow.fireWindowCreated(Unknown Source)
at org.eclipse.ui.internal.WorkbenchWindow.open(Unknown Source)
at org.eclipse.ui.internal.Workbench$22.runWithException(Unknown Source)
at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(Unknown Source)
at org.eclipse.swt.widgets.Synchronizer.syncExec(Unknown Source)
at org.eclipse.ui.internal.UISynchronizer.syncExec(Unknown Source)
at org.eclipse.swt.widgets.Display.syncExec(Unknown Source)
at org.eclipse.ui.internal.StartupThreading.runWithWorkbenchExceptions(Unknown Source)
at org.eclipse.ui.internal.Workbench.busyOpenWorkbenchWindow(Unknown Source)
at org.eclipse.ui.internal.Workbench.access$29(Unknown Source)
at org.eclipse.ui.internal.Workbench$51.run(Unknown Source)
at org.eclipse.swt.custom.BusyIndicator.showWhile(Unknown Source)
at org.eclipse.ui.internal.Workbench.openWorkbenchWindow(Unknown Source)
at com.ibm.rcp.personality.framework.internal.RCPWorkbenchAdvisor$NewWindowRunnable.run(Unknown Source)
at com.ibm.rcp.personality.framework.internal.RCPWorkbenchAdvisor.openPersonality(Unknown Source)
at com.ibm.rcp.personality.framework.internal.RCPWorkbenchAdvisor.openPersonality(Unknown Source)
at com.ibm.rcp.personality.framework.internal.RCPWorkbenchAdvisor$4.runInUIThread(Unknown Source)
at org.eclipse.ui.progress.UIJob$1.run(Unknown Source)
at org.eclipse.swt.widgets.RunnableLock.run(Unknown Source)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Unknown Source)
at org.eclipse.swt.widgets.Display.runAsyncMessages(Unknown Source)
at org.eclipse.swt.widgets.Display.readAndDispatch(Unknown Source)
at org.eclipse.ui.internal.Workbench.runEventLoop(Unknown Source)
at org.eclipse.ui.internal.Workbench.runUI(Unknown Source)
at org.eclipse.ui.internal.Workbench.access$4(Unknown Source)
at org.eclipse.ui.internal.Workbench$5.run(Unknown Source)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Unknown Source)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Unknown Source)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(Unknown Source)
at com.ibm.rcp.personality.framework.internal.RCPApplication.run(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.internal.app.EclipseAppContainer.callMethodWithException(Unknown Source)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(Unknown Source)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(Unknown Source)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(Unknown Source)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(Unknown Source)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Unknown Source)
at org.eclipse.equinox.launcher.Main.basicRun(Unknown Source)
at org.eclipse.equinox.launcher.Main.run(Unknown Source)
at com.ibm.rcp.core.internal.launcher.Main.startLaunch(Unknown Source)
at com.ibm.rcp.core.internal.launcher.Main.main(Unknown Source)
at com.ibm.rcp.core.internal.launcher.Main.run(Unknown Source)
回答1:
I tend to go through the process of exporting the update site and installing from there into Domino Designer. You can manually add the plugin file to the relevant folder of Domino Designer (/framework/shared/eclipse/plugins I believe), but I'm pretty sure you'll still need to restart Notes and Designer to pick up any changes.
faces-config files tend to defined in the getFacesConfig method of the library - that's what I used in XPages OpenLog Logger. It looks like it gets called automatically. The java class doesn't have to be a different name from what you've used before, as long as the original faces-config reference is removed. Because the beans are just instances of the class, you could create an object that extends DataObject and put it in the relevant scope in a createImplicitObjects method - there's an example in the ImplicitObjectFactory class to add "server" to requestScope. In OpenNTF Domino API the same thing is done to register a variety of objects. But you may need to handle disposing of the object. The faces-config approach should be easier and that code shouldn't get called until runtime. If there's an error, you can use logging writing to a text file or server console or OpenLog (if you make it dependent on XPages OpenLog Logger or OpenNTF Domino AP. But you can also debug once it's running on the server using the debug plugin.
I agree that plugins are very powerful and it really opens up the extensibility of XPages.
回答2:
use the Debug Plug-in for Eclipse. When you configure it, it will create the necessary links (basically working like .dir files in classic Notes) in your Domino server structure, so the plug-in project gets directly loaded from your Eclipse instance. It does require a local server.
Alternatively you could use a build script that does the copying of your plug-in to a remote server. Way more work and unless you fancy getting to know build scripts not worth the effort
回答3:
Instead of developing your backing beans and app-specific java in the nsf you can make another application specific XspLibrary and develop that from eclipse as well.
this has the benefit that you can do all your remote debugging from eclipse (code changes are "hot swapped" without restart of http for minor changes) also refactoring is easier as you will see the effects changes to your global library have on your app library.
unless you are developing your own ui components, there will be no need to update domino designer with latest versions etc. you will need to install your app-specific library to designer once so that designer is happy to resolve the dependency you put in xsp.properties.
if you are using source control, you can have 2 separate folders in your repository, one for your nsf and one for your plugin. this keeps your xpages/custom controls in step with your java from a management perspective.
downside is deployment but if you are deploying plugins already you can deploy in the same fashion. we have a Jenkins server that deploys both the nsf and plugins but that is another kettle of fish :)
来源:https://stackoverflow.com/questions/24368293/domino-osgi-dev-and-testing-what-about-a-designer-connection