Home » Eclipse Projects » Eclipse Scout » Groovy support?(What's required to support the Groovy language within Scout projects?)
Groovy support? [message #1219270] |
Tue, 03 December 2013 04:56 |
Patrick Mackinlay Messages: 10 Registered: December 2013 |
Junior Member |
|
|
I'm new to Scout, and while I don't have much experience with Java, I've been using Groovy professionally for a number of years (in a "scripting" capacity), and I appreciate many of its benefits over native Java. I'd really like to be able to use Groovy within Scout projects, but I don't know enough about the framework and OSGi and related topics to help myself.
I converted my Scout server project to a Groovy project, and without making any other changes, things still work fine. When I attempt to change my DesktopService to a Groovy class without actually changing any of its implementation, the server starts fine but I get the following exception when trying to start the client (SWT, in my case).
!ENTRY org.eclipse.scout.rt.client 4 0 2013-12-03 11:40:13.849
!MESSAGE org.eclipse.scout.rt.client.services.common.exceptionhandler.internal.InternalClientExceptionHandlerService.differentiatedLog(InternalClientExceptionHandlerService.java:116) ProcessingException: ProcessingStatus[ERROR code=0 DesktopForm / Calling IDesktopService.load() / Processing error]
!STACK 0
ProcessingException[ProcessingStatus[ERROR code=0 DesktopForm / Calling IDesktopService.load() / Processing error]]
at org.eclipse.scout.rt.client.servicetunnel.AbstractServiceTunnel.invokeService(AbstractServiceTunnel.java:167)
at org.eclipse.scout.rt.client.servicetunnel.http.internal.InternalHttpServiceTunnel.invokeService(InternalHttpServiceTunnel.java:175)
at org.eclipse.scout.rt.client.servicetunnel.http.HttpServiceTunnel.invokeService(HttpServiceTunnel.java:115)
at org.eclipse.scout.rt.client.servicetunnel.ServiceTunnelInvocationHandler.invoke(ServiceTunnelInvocationHandler.java:47)
...
I think the problem is related to the way in which the Groovy class loader works in combination with the service registration logic, and I've found the following page about using Groovy within OSGi: groovy.codehaus.org/OSGi+and+Groovy (seems I don't have rights to make an actual link yet). In particular, there's a section about how the Activator for Groovy classes needs to be programmed a bit differently to regular Java.
Can anybody who's more knowledgeable about this subject help me out? Am I foolish to think I can combine these two excellent technologies in my project?
|
|
| |
Re: Groovy support? [message #1220308 is a reply to message #1220265] |
Wed, 11 December 2013 02:02 |
Patrick Mackinlay Messages: 10 Registered: December 2013 |
Junior Member |
|
|
Thanks for your interest, Jeremie.
I just set up a new test case project for this particular issue, by doing the following:
- Created new Scout project using single form template
- Created a new "TestService" with a single test() operation.
- Created a new Test menu item which just calls and logs the result from the test() service operation call.
Obviously, this all works fine without introducing Groovy. After using "Convert to Groovy project" on the server project, things still work fine. Then after converting my TestService.java class to a Groovy file (TestService.groovy), the Test menu item code (i.e. calling the TestService.test() service operation) doesn't work any more.
I'd discovered the way to view the server log myself, but hadn't retraced this particular problem to see what it would reveal, so thanks for your prompt.
There are two exceptions on the server side. The first is caused by the service registration failing, and the second is the failure to find and execute the service operation (a result of the earlier problem), so I'll only include the first exception here:
!ENTRY org.eclipse.scout.service 4 0 2013-12-11 08:39:02.978
!MESSAGE org.eclipse.scout.service.internal.ServicesExtensionManager.added(ServicesExtensionManager.java:195) register service: bundle=org.eclipse.groovytest.server, service=org.eclipse.groovytest.server.services.TestService
!STACK 0
java.lang.NoClassDefFoundError: groovy/lang/GroovyObject
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.defineClass(DefaultClassLoader.java:188)
at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.defineClassHoldingLock(ClasspathManager.java:638)
at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.defineClass(ClasspathManager.java:613)
at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findClassImpl(ClasspathManager.java:574)
at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClassImpl(ClasspathManager.java:492)
at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass(ClasspathManager.java:465)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLocalClass(DefaultClassLoader.java:216)
at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:395)
at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:464)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:421)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:412)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:340)
at org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:229)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1212)
at org.eclipse.scout.service.internal.ServicesExtensionManager.added(ServicesExtensionManager.java:105)
at org.eclipse.scout.commons.runtime.ExtensionPointTracker.open(ExtensionPointTracker.java:112)
at org.eclipse.scout.service.internal.ServicesExtensionPointTracker.access$0(ServicesExtensionPointTracker.java:1)
at org.eclipse.scout.service.internal.ServicesExtensionPointTracker$1.run(ServicesExtensionPointTracker.java:45)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:53)
Caused by: java.lang.ClassNotFoundException: groovy.lang.GroovyObject cannot be found by org.eclipse.groovytest.server_1.0.0.qualifier
at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:501)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:421)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:412)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 23 more
So looking at this, it seems fairly clear that the ServicesExtensionManager class doesn't know how to deal with the Groovy class being supplied - it sees it as a groovy.lang.GroovyObject instead of the org.eclipse.groovytest.server.services.TestService class that it's expecting. Although my understanding is limited, I think this goes back to the initial posting, that perhaps there's some different method required to load the class when it's a Groovy one, versus a regular Java one.
In the short term, my aim is simply to take advantage of the Groovy language "syntactical sugar", to make my code more compact and more "functional", on both the client and server side if possible. It's my opinion that equivalent code sequences are far shorter in Groovy, and this can often lead to fewer defects; of course all this is subjective, and I don't want to start a language war.
In the longer term, the actual project I'm working on requires a fairly dynamic data model (e.g. each customer can add and remove their own fields and relationships between objects), while still being stored in a single centralised repository. It's my opinion that the dynamic language features of Groovy allow this to be achieved with far fewer "hoop jumping" than would otherwise be necessary with straight Java.
Thanks again for taking an interest - I might now take a look at the ServicesExtensionManager implementation myself to see if anything jumps out...
|
|
| |
Re: Groovy support? [message #1220501 is a reply to message #1220337] |
Thu, 12 December 2013 08:54 |
Patrick Mackinlay Messages: 10 Registered: December 2013 |
Junior Member |
|
|
Thanks again Stephan, this seems to have done the trick, and I'm now able to call a service which is implemented as a Groovy class (and I'm able to use Groovy syntax as expected).
Since I'm a complete noob when it comes to this, I wanted to post the steps I performed in Eclipse in order to get this to work, and I hope someone can confirm if this is the correct process, or if there's a more "correct" way to achieve it:
First, imported the "groovy-all" plugin into my workspace in Eclipse:
- Launched the Eclipse IDE "File/Import" menu option
- Selected "Plug-ins and Fragments"
- Selected "Directory", and pointed at a folder that contained the groovy-all-*.jar file (this is the "embeddable" folder of a regular Groovy installation)
- Left the other two options alone at "Select..." and "Binary projects"
- Added the only option shown, which was the groovy-all plug-in
Next, opened my Scout server application's MANIFEST.MF, switched to the "Dependencies" tab, and used the "Add..." button to add the new "groovy-all" plugin to the set of "Required Plug-ins".
Finally, opened the Scout server "product" file, switched to the "Dependencies" tab, and clicked the "Add Required Plug-ins", which added the "groovy-all" plug-in to the list.
After completing those steps, my Groovy-implemented service started registering and working properly. I expect I can follow a similar process to implement with Groovy code on the client side too.
Is there a more correct way to perform this configuration, either directly via a Scout SDK operation or similar, or am I doing it the "right way" already?
|
|
|
Goto Forum:
Current Time: Wed Apr 24 15:04:21 GMT 2024
Powered by FUDForum. Page generated in 0.03518 seconds
|