Groovy script classpath issue with SystemClassLoader - groovy

I'm writing a Groovy script which uses third party java code that I can't change.
This code uses (badly, I think) ClassLoader.getSystemClassLoader().getResourceAsStream("/hard/file/path/in/jar/file")
and expect to read a file.
Everything goes well from Java when using java -cp "/path/to/jar/file" ...
However, the third-party code is now to be integrated with a bunch of Groovy code we've already written, so we wanted to run it from groovy.
So we wrote a Groovy script, let it call test.groovy, and ran it as groovy -cp "/path/to/jar/file" test.groovy.
The problem is that code can't access the file resource, as it seems Groovy doesn't load its jars in the System ClassLoader directly.
For proof, with Thread.currentThread().getContextClassLoader().getResourceAsStream("/hard/file/path/in/jar/file") within the Groovy Script, I can read the file, but with ClassLoader.getSystemClassLoader().getResourceAsStream("/hard/file/path/in/jar/file"), I can't.
So, does anyone know how to load the class in System ClassLoader from a Groovy Script without beginning to try some dirty hacks (like metaclassing getSystemClassloader to return the context classloader)?

You could try adding the jar to the system classloader as well when your script runs, like so:
ClassLoader.systemClassLoader.addURL new File( '/path/to/jar/file' ).toURI().toURL()
PS: I assume you mean ClassLoader.getSystemClassLoader() in your question, rather than System.getSystemClassLoader()

You can try to put your jar into %GROOVY_HOME%\lib folder or make a wrapper around your groovy command and modify %CLASSPATH% variable before you start your Groovy process.

Related

How can I use Groovy classes in other packages without JAR?

I'm pretty new to Groovy (coming from Java), so this may be a stupid question :-)
Nonetheless: I'd like to structure a couple of Groovy scripts using packages. And I'd like to import some general Groovy classes from some other package.
How can I make sure that my Groovy scripts finds the other classes in the other packages? The only classpath related files I can remember are JARs.
If you from java:
Groovy loads classes as java and also includes non-compiled with extension .groovy.
So, you have to place your classes relative to classpath according to their package name.
The command line should be something like this:
groovy -cp "path_to_classes_root" "path_and_name_of_main_groovy_script.groovy"

Reusing the groovy code in multiple Groovy Script test steps of SoapUI

I created functions(methods)in step1 using groovy in soapUI(open source) and calling in step2, it is not getting called, It is getting called only to that step1. I want to make those functions as global. can any one suggest me how to do that?
In order to achieve, what you are looking for is, to do the following:
Create classes (either in groovy or java of your preferred language)
Add the reusable methods into those classes
Compile the classes and create jar file
Copy the jar under SOAPUI_HOME/bin/ext directory
Restart the soapui tool
Now you should be able to call the reusable method from any of your project /test suite / test case/ test step.
Hope this is useful.

Runnable jar with Apache POI

I'm trying to export my program as a runnable jar, packing the necessary libraries (Apache POI). The .jar is created, but it doesn't work. Is there a catch on deploying with these libraries? Because the program itself runs great from eclipse.
A few questions to ask yourself in this situation:
Where does the program fail? Are there any errors in the console? Are you running from the command line (java -jar myJAR.jar) so that you can see console output?
Okay, so you get a NullPointerException for the read file. Is the read file inside the JAR, or where is it? How does the program know where the read file is?
Is there really a problem with the way the JAR is packaged, or is it the way your code locates and reads in the file? Perhaps your code assumes a relative location which cannot be resolved when run from the JAR.
There are the following strategies.
Create your jar. Put it to chosen directory. Put there all dependencies of your application. Create script (shell script, batch file etc depending on your platform) where the java command line is either written hard coded or is generated. The line must include the class path, e.g.
java -cp myapp.jar;poi.jar com.company.MyMain
Create indeed runnable jar, i.e. jar that can be executed using command like java -jar myapp.jar. If your application has dependencies this jar must have MANIFEEST.MF file that defines class path using property Class-Path
Pack all your classes and all your dependencies into one large jar file.
Obviously all these operations should be automated either home made script or by one of available build tools.

How to run a set of dependent groovy scripts without compilation?

I've got a set of groovy scripts (or should I say a groovy app) which has hierarchical java alike package structure and script names the same as class names. All of them are called from the main script (like a java class with main method). I need to call just that particular main script and get all other scripts executed in sequence when needed (or loaded and executed).
Practically, this can be acieved by having all scripts compiled and .class files obtained and put into classpath while running the main script, but that's quite redundant for a scripting (the idea is to have it working without compilation, even though groovy will do it somwhere behind the scene)
How can I achieve it?
Groovy can be used in a scripting environment quite easily - no compile step required. Read this:
http://groovy.codehaus.org/Running
You can write your usual main method etc. and call it like this,
groovy -cp foo/ foo/MyScript.groovy [arguments]
Or if you're in a *nix environment you can give it a shebang like so,
#!/usr/bin/env groovy
println("Hello world")
for (a in this.args) {
println("Argument: " + a)
}
and run it using ./fileName (provided you've marked it as executable)

Run groovy script from within gradle

What's the best way to create a gradle task, which runs a groovy script? I realize that gradle build files are groovy, so I would think it would be possible to do something like this:
task run << {
Script app = new GroovyShell().parse(new File("examples/foo.groovy"))
// or replace .parse() w/ a .evalulate()?
app.run()
}
I get all kinds of whacky errors when I try this if bar.groovy is using #Grab annotations or even doing simple imports. I want to create a gradle task to handle this, so that I can hopefully reuse the classpath definition.
Would it be better to move the examples directory into the src directory somewhere? What's a best practice?
Or you could do:
new GroovyShell().run(file('somePath'))
You could try using GroovyScriptEngine instead of the GroovyShell. I've used it previously with #Grab annotations. You will need all of groovy on the classpath, the groovy-all.jar will not be enough. I'm guessing Ivy isn't packaged in the groovy-all.jar. Something like this should to the trick:
This script presumes a groovy script at /tmp/HelloWorld.groovy
def pathToFolderOfScript = '/tmp'
def gse = new GroovyScriptEngine([pathToFolderOfScript] as String[])
gse.run('HelloWorld.groovy', new Binding())
http://wayback.archive.org/web/20131006153845/http://docs.codehaus.org/display/GRADLE/Cookbook#Cookbook-runningthingsfromGradle
ant.java(classname: 'com.my.classname', fork: true,
classpath: "${sourceSets.main.runtimeClasspath.asPath}")
I think you probably need to run the script as a new process... e.g.,
["groovy","examples/foo.groovy"].execute()
I would guess that the way Gradle is executed is not via invoking groovy, so the setup that makes #Grab work never happens. It could also be the the version of Groovy that Gradle uses doesn't support #Grab.

Resources