Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » scout » Groovy support?(What's required to support the Groovy language within Scout projects?)
Groovy support? [message #1219270] Mon, 02 December 2013 23:56 Go to next message
Patrick Mackinlay is currently offline 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 #1220265 is a reply to message #1219270] Tue, 10 December 2013 12:59 Go to previous messageGo to next message
Jeremie Bresson is currently offline Jeremie Bresson
Messages: 529
Registered: October 2011
Senior Member
What is the stacktrace in the server?

You can switch the console output to display the server console with this button:
index.php/fa/14767/0/

Just to clarify something before I spend time to investigate this, your idea is to include Groovy as dependency in the scout server and to implement a Scout Service with Groovy?
May I ask why? Is it because you are more comfortable with the Groovy Language? Will you need the dynamic nature of the language? How? I am very interested in your use case. It sounds interesting.

I had a look at the page you have mentioned:
http://groovy.codehaus.org/OSGi+and+Groovy
(I think you need more posts to be able to post link... It is a security configuration controlled by the eclipse.org webmaster, sorry about it).

From what I have read, it should be possible to use Groovy in a Scout application...
Re: Groovy support? [message #1220308 is a reply to message #1220265] Tue, 10 December 2013 21:02 Go to previous messageGo to next message
Patrick Mackinlay is currently offline 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:


  1. Created new Scout project using single form template
  2. Created a new "TestService" with a single test() operation.
  3. 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 #1220337 is a reply to message #1220308] Wed, 11 December 2013 03:18 Go to previous messageGo to next message
Stephan Leicht Vogt is currently offline Stephan Leicht Vogt
Messages: 99
Registered: February 2010
Location: Baden Switzerland
Member

Hi Patrick

This looks indeed very interesting. By the look of the exception it seems, that your server project, org.eclipse.groovytest.server, is missing the "plugin-dependency dependency" to the groovy plugin or the "import package" to groovy.lang in the MANIFEST.MF.

Greetings
Stephan
Re: Groovy support? [message #1220501 is a reply to message #1220337] Thu, 12 December 2013 03:54 Go to previous message
Patrick Mackinlay is currently offline 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:

  1. Launched the Eclipse IDE "File/Import" menu option
  2. Selected "Plug-ins and Fragments"
  3. Selected "Directory", and pointed at a folder that contained the groovy-all-*.jar file (this is the "embeddable" folder of a regular Groovy installation)
  4. Left the other two options alone at "Select..." and "Binary projects"
  5. 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?
Previous Topic:How to participate in service transactions?
Next Topic:How To add Tabs to TabBox programmatically
Goto Forum:
  


Current Time: Wed Apr 16 21:07:34 EDT 2014

Powered by FUDForum. Page generated in 0.01737 seconds