FYI, while porting Jexler from Java to Groovy I found a use
case for Grengine (http://grengine.ch/) that might be interesting
to some - not for running the Jexler Groovy scripts as services,
for that I use a normal GroovyClassLoader - but for scheduling
something using Quartz (http://quartz-scheduler.org).

The interface for a Job to schedule in Quarz is a bit strange,
maybe not without good reasons, but anyway: you have to
implement the Job interface with a class that has a no args
constructor and has a "void execute(def context)" method.
That makes it difficult to give the method some useful context
because only serializable objects can be provided there.

Instead I did this:

class SomeUtil {

    private static final Grengine gren = new Grengine()

    private static final String runnableWrappingJobScript = """\
        import groovy.transform.CompileStatic
        import org.quartz.*
        @CompileStatic
        class RunnableWrappingJob implements Job {
           public static Runnable runnable
          RunnableWrappingJob() {}
void execute(JobExecutionContext context) throws JobExecutionException {
             runnable.run()
          }
        }
        """.stripIndent()

    static {
        gren.load(runnableWrappingJobScript)
    }

    static Class newJobClassForRunnable(Runnable runnable) {
Class jobClass = (Class)gren.load(gren.newDetachedLoader(), runnableWrappingJobScript)
        jobClass.getDeclaredField('runnable').set(null, runnable)
        return jobClass
    }

}

This way, I can simply pass anything that implements runnable:

The way Grengine is used, each time someone requests a new Job class
for a given runnable, Grengine uses the already compiled bytecode and
loads the class from a new ClassLoader, and then via reflection the *static*
variable "runnable" is set...

(I you don't mind to compile each time, you could of course also use a
GroovyClassLoader here or redirect output to a class file and add that
to a second GroovyClassLoader, with a little more complexity).

In any case, since the solution with Grengine is quite lean, it might be
useful in other similar cases...?

Alain

On 20.05.15 15:05, Alain Stalder wrote:
I wrote when announcing Jexler 1.0.6 a week ago:
> "Jexler is a simple relaxed Java 7 framework for
> starting/stopping Groovy scripts as services and
> enabling them to react to events of their choice."

Well, not any more! Now it's written 100% in Groovy:

2.0.0 (2015-05-20)
* Jexler is now written in Groovy (unit tests with Spock),
  no longer Java 7 (and JUnit).
* Scheduling is now based on Quartz, no longer on Cron4j,
  which allows now to schedule at shorter intervals
  (seconds instead of minutes).
* Various small changes and simplifications, which should
  almost always have no effect on existing jexler scripts.

Porting Jexler from Java to Groovy has been a lot of fun,
things just got simpler...*

Spock especially is fantastic, thanks for making it!

Fascinating... ;)

Alain

* I am using Intellj IDEA - at least a year ago Groovy support
in Eclipse was not good enough (yet?) so that I had cancelled
a similar attempt back then... :(

PS: http://www.jexler.net/

Reply via email to