Start from Java/Groovy

  • Lars Soltau
    Lars Soltau

    I am trying to start a Java application contained in a one-jar file from a Groovy script. Since I am already running in a JVM, it seems cumbersome to start the application externally.

    This is what I've done:


    // add one-jar file to my class path
    def loader = this.class.classLoader.rootLoader

    // tell one-jar where its jar file lies
    System.setProperty('one-jar.jar.path', jarfile.path)

    String[] a = [myfile.path]
    Class c = Class.forName('com.simontuffs.onejar.Boot')
    java.lang.reflect.Method m = c.getMethod('main', [a.getClass()] as Class[])
    try {
        m.invoke(null, [a] as Object[])
    catch (java.lang.reflect.InvocationTargetException e) {


    Now I get the application to start, but there is a resource file in the jar, loaded by the application. This works fine if I start the jar from the shell, but when I start it from inside my Groovy script, I get the following output:


    JarClassLoader: Info: findResource(my/pkg/
    JarClassLoader: resource my/pkg/ resolved to my/pkg/
    JarClassLoader: Info: findResource found: my/pkg/
    JarClassLoader: Warning: unable to locate my/pkg/ due to unknown protocol: onejar


    and the application fails, unable to read its resource bundle.

    So, apparently the proprietary URL protocol onejar doesn't get registered. Any idea how to fix this?

    • P. Simon Tuffs
      P. Simon Tuffs

      Well, I think you're almost there!  I'm not at my dev. machine right now, but the solution is contained in the source-code; look for the protocol registration mechanism in /com/simontuffs/onejar/Handler.jar, then look for how this handler is registered. 

      This should solve your problem, let me know how it goes.

    • Lars Soltau
      Lars Soltau

      So, after a good look at the source and the javadoc for URL and friends, it seems that the mechanism for searching for URLStreamHandlers in all packages specified in the system property doesn't work.

      I tried including the one-jar file in the classpath (although I didn't like that idea), I even preloaded com.simontuffs.onejar.Handler, but nothing worked.

      So I had to define a new URLStreamHandlerFactory in my script and install that. The script works now, but I haven't found any method for passing unknown URL protocols to already installed factories, à la chained event handlers and the like.

      Here's my snippet of code (calling the constructor for Handler statically, I'll switch this to reflection of course so I won't have to include the one-jar file in the classpath).

      ----8<--------8<--------8<---- OnejarFactory())


      class OnejarFactory implements URLStreamHandlerFactory {
      public OnejarFactory() {}
      public URLStreamHandler createURLStreamHandler(String protocol) {
      if (protocol.equals('onejar')) {
      return new com.simontuffs.onejar.Handler()
      return null