Grape seems to work fairly well for adding jars to your classpath. It also does a lot of other things such as fetching and dependency management. e.g.
#!/home/robert/bin/groovy
import org.apache.commons.lang.StringUtils
@Grab(group='commons-lang', module='commons-lang', version='2.4')
def strings = ['Hello', 'Groovy', 'AVeryLongWord!', 'A simple sentence']
strings.each { String aString ->
println "$aString: ${StringUtils.abbreviate(aString,10)}"
}
Unfortunately if there is a jar on my filesystem that I want to dynamically add to the filesystem then I have to resort to a much uglier solution.
#!/home/robert/bin/groovy
def loader = this.class.classLoader.rootLoader
loader.addURL(new File("/home/robert/somejars/arithmetic-1.1.jar").toURI().toURL())
// can't use traditional package import
arithmeticMainClass = Class.forName("org.scharp.arithmetic.Main")
println "42 - 23 = " + arithmeticMainClass.subtract(42, 23)
// can't use "new" operator
myArithmeticObject = arithmeticMainClass.newInstance()
Is there a way to make grape grab a jar from the filesystem? If not, can I somehow replicate what grape is doing in groovy/java?
I would like this solution to work for scripts that can be run by many users and many incompatible jars so adding jars to a common directory such as ~/.groovy/lib/ won't work.
I could create a local maven repository for local, jar libaries but that seems like overkill.
This is how I solved this.
When Grape (Ivy) wants something it caches it under the ~/.groovy/grapes
directory. All you need to do is just create your own ivy.xml file and throw your jar in there. I figured it out by just looking at some of the other artifacts donwloaded from maven. Here is a small example.....
We use Oracle here and I wanted it's jdbc jar file to be able to be 'Grabbed' by my Groovy scripts. Unfortunately, I could not find any repository that had this jar on the web.
~/.groovy/grapes/com.oracle
~/.groovy/grapes/com.oracle/ojdbc6
~/.groovy/grapes/com.oracle/ojdbc6/jars
Here is my xml.
<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0" xmlns:m="http://ant.apache.org/ivy/maven"
>
<info organisation="com.oracle" module="ojdbc6" revision="11.2.0.1.0" status="release" publication="20130102153401">
<license name="" />
<description homepage="">Oracle ojdbc driver</description>
</info>
<configurations>
<conf name="default" visibility="public" description="" extends="runtime,master" />
<conf name="master" visibility="public" description="" />
<conf name="compile" visibility="public" description="" />
<conf name="provided" visibility="public" description="" />
<conf name="runtime" visibility="public" description="" extends="compile" />
<conf name="test" visibility="public" description="" extends="runtime" />
<conf name="system" visibility="public" description="" />
<conf name="sources" visibility="public" description="" />
<conf name="javadoc" visibility="public" description="" />
<conf name="optional" visibility="public" description="" />
</configurations>
<publications>
<artifact name="ojdbc6" type="jar" ext="jar" conf="master" />
</publications>
</ivy-module>
Now I can use this jar in my groovy scripts with the following....
@Grapes([
@GrabConfig(systemClassLoader=true),
@Grab('com.oracle:ojdbc6:11.2.0.1.0'),
])
import groovy.sql.*
To make things easy for deploying this grape to multiple servers I created a zip file that I could extract anywhere....
$ unzip -qql oracle_jdbc_groovy_grape.zip
0 06-11-2012 13:50 .groovy/grapes/com.oracle/
0 06-12-2012 14:17 .groovy/grapes/com.oracle/ojdbc6/
0 06-12-2012 14:17 .groovy/grapes/com.oracle/ojdbc6/jars/
2111220 06-11-2012 11:46 .groovy/grapes/com.oracle/ojdbc6/jars/ojdbc6-11.2.0.1.0.jar
2349 06-11-2012 11:50 .groovy/grapes/com.oracle/ojdbc6/ivy-11.2.0.1.0.xml