I'm trying to write a Groovy script that depends on the HTTPBuilder library. I'm trying to add this as a dependency of my script via the #Grab annotation shown below
#Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.7.1')
import groovyx.net.http.HTTPBuilder
// rest of script omitted
But when I run this script I get the error:
java.lang.RuntimeException: Error grabbing Grapes -- [download failed: commons-lang#commons-lang;2.4!commons-lang.jar]
I've tested using #Grab to add other dependencies to my script, and the same problem does not occur, why can't I add HTTPBuilder?
Grape may be configured to only look in your local Maven repo for dependencies. To instruct it to also check online repositories, create a config. file ~/.groovy/grapeConfig.xml and add something like the following to it
<ivysettings>
<settings defaultResolver="downloadGrapes"/>
<resolvers>
<chain name="downloadGrapes">
<filesystem name="cachedGrapes">
<ivy pattern="${user.home}/.groovy/grapes/[organisation]/[module]/ivy-[revision].xml"/>
<artifact pattern="${user.home}/.groovy/grapes/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]"/>
</filesystem>
<!-- todo add 'endorsed groovy extensions' resolver here -->
<ibiblio name="codehaus" root="http://repository.codehaus.org/" m2compatible="true"/>
<ibiblio name="ibiblio" m2compatible="true"/>
<ibiblio name="java.net2" root="http://download.java.net/maven/2/" m2compatible="true"/>
</chain>
</resolvers>
</ivysettings>
Related
Disclaimer: Ant Noob!
I'm trying to get the groovy task running in ant. Works so far:
<project>
<taskdef name="groovy"
classname="org.codehaus.groovy.ant.Groovy"
classpath="C:/Local/groovy-2.4.5/lib/groovy-ant-2.4.5.jar;C:/Local/groovy-2.4.5/lib/groovy-2.4.5.jar"/>
<echo message="Hello!"/>
<groovy>
println "Hello from Groovy!"
</groovy>
</project>
What I can't get behind (even reading this and related entries) is what I need to do to my Ant installation (Windows) to make the script run like so, without the taskdef or any other reference in my project specific build file:
<project>
<echo message="Hello!"/>
<groovy> <!-- Would be nice if I could treat this like a built-in -->
println "Hello from Groovy!"
</groovy>
</project>
You'll need to put all Groovy dependencies (groovy-ant.jar, groovy.jar, etc) on the classpath that is read by Ant. The easiest way is to store them under ANT_HOME/lib. Or you can pass them using the -lib option on the command line.
Then you would still have to tell Ant about the path of the antlib. You can use the antlib namespace mechanism described in the documentation page. You specify the package that contains the antlib.xml in the namespace URI, in this case org.codehaus.groovy:
<project xmlns:groovy="antlib:org.codehaus.groovy">
<echo message="Hello!"/>
<groovy:groovy>
println "Hello from Groovy!"
</groovy:groovy>
</project>
Note that you can still use taskdef without referencing the Jar file if it is placed (with its dependencies) in ANT_HOME/lib. You just reference the path of the antlib resource in the Jar. In this case you can do without the namespace URI:
<project>
<taskdef resource="org/codehaus/groovy/antlib.xml"/>
<echo message="Hello!"/>
<groovy>
println "Hello from Groovy!"
</groovy>
</project>
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.
Step 1 : create directory ~/.groovy/grapes/com.oracle
Step 2 : create directory ~/.groovy/grapes/com.oracle/ojdbc6
Step 3 : create directory ~/.groovy/grapes/com.oracle/ojdbc6/jars
Step 4 : Get a copy of Oracle's ojdbc jar file and rename it. Our oracle version is 11.2.0.1.0 and we use Java6 so I got the locally installed ojdbc6.jar file and copied as ojdbc6-11.2.0.1.0.jar. This file I put into the directory created in the prior step.
Step 5 : create an ivy-11.2.0.1.0.xml config file.This file should be put into the directory created in step 2. For this step I heavily relied on examples from other artifacts grabbed. Any apache commons lib is a good example.
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
You can customize the ivy settings that Grape uses by creating a ~/.groovy/grapeConfig.xml file.
Here's an example how to use the local file system as repository:
<ibiblio name="local" root="file:${user.home}/.m2/repository/" m2compatible="true"/>
There's been some interest in adding this feature to grape but nothing serious. My guess is that it's unlikely that this will be added in the near future. (6-18 months)
According to this enhancement, Grapes will now also search your local Maven repo, along with Maven Central.
You can install any jar(s) in your local repo by:
running mvn install in your project
using mvn dependecy:get; see documentation and example
using mvn install:install-file; see documentation and example
A sample script ss.groovy:
#Grab(group='org.codehaus.groovy.modules.http-builder',
module='http-builder',
version='0.5.0')
import groovyx.net.http.HTTPBuilder
println('done')
for some reason takes ~25 seconds to load when run with
groovy ss.groovy
and ~5 seconds when run with
groovy -Dgroovy.grape.autoDownload=false ss.groovy
as per this StackOverflow explanation. I tried doing manual initialization with
Grape.enableAutoDownload = false
Grape.grab(group:'org.codehaus.groovy.modules.http-builder',
module:'http-builder',
version:'0.5.0')
import groovyx.net.http.HTTPBuilder
println('done')
but this fails on import with:
/tmp/ss.groovy: 3: unable to resolve class groovyx.net.http.HTTPBuilder
# line 3, column 1.
import groovyx.net.http.HTTPBuilder
^
Is there a contained way to either:
Make it not download the artifacts automatically (preferred, as it allows for solving other issues, e.g. external site down while an artifact already exists in the local cache)
Make it startup faster in any other way
By contained I mean that all additional instructions should be either within script or, if no such one exists, an acceptable default (e.g. don't check the cached artifacts for updates - I would still, however, like to have automatic downloads globally) to be put in some of groovy config files (e.g. ~/.groovy/grapeConfig.xml or similar).
Update: The issue has been fixed, #GrabConfig(autoDownload=false) will be available in Groovy 2.2
Why not install a repository manager locally?
http://nexus.sonatype.org/
I use Nexus to proxy and cache all my 3rd party repositories. Groovy is the configured to retrieve from either it's local cache or Nexus:
<ivysettings>
<settings defaultResolver="downloadGrapes"/>
<resolvers>
<chain name="downloadGrapes">
<filesystem name="cachedGrapes">
<ivy pattern="${user.home}/.groovy/grapes/[organisation]/[module]/ivy-[revision].xml"/>
<artifact pattern="${user.home}/.groovy/grapes/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]"/>
</filesystem>
<!-- Local Nexus Repository -->
<ibiblio name="nexus" root="http://localhost:8081/nexus/repositories/public" m2compatible="true"/>
</chain>
</resolvers>
</ivysettings>
This doesn't seem to be possible with the current (Groovy 1.8.1) implementation. I created an improvement ticket: http://jira.codehaus.org/browse/GROOVY-4943.
I've noticed there is like a 10 second hit using a groovy script with Grape annotations on my OSX box. Is it always this way? Can I make grape favor its cache (the depedencies are definitely already on the system in ~/.groovy/grapes...).
Some libraries (notably httpbuilder) use version ranges in their dependencies. There is a post here which describes how to increase the TTL for this version check in your grapeconfig.xml file.
Do you have a ~/.groovy/grapeConfig.xml file defined? The example given in the doco favours the local cache.
<ivysettings>
<settings defaultResolver="downloadGrapes"/>
<resolvers>
<chain name="downloadGrapes">
<filesystem name="cachedGrapes">
<ivy pattern="${user.home}/.groovy/grapes/[organisation]/[module]/ivy-[revision].xml"/>
<artifact pattern="${user.home}/.groovy/grapes/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]"/>
</filesystem>
<!-- todo add 'endorsed groovy extensions' resolver here -->
<ibiblio name="codehaus" root="http://repository.codehaus.org/" m2compatible="true"/>
<ibiblio name="ibiblio" m2compatible="true"/>
<ibiblio name="java.net2" root="http://download.java.net/maven/2/" m2compatible="true"/>
</chain>
</resolvers>
</ivysettings>
We've been using CruiseControl.Net for a couple of years now and it has been working fine. However, since our last upgrade a few weeks ago to the latest version (1.5.0.6237) our build reports are failing to display on the ccnet website. Instead we get the following message:
"BUILD FAILED
Project: TX
Date of build: 2010-06-22 23:41:54
Running time: 00:05:06
Integration Request: Build (ForceBuild) triggered from ScheduleTrigger
Last changed: 2010-06-22 15:14:14
Last log entry: Merge Branches:
Origin=$/Source/RE/Branches/3.1
Version: 2629 [DT- 3652]: Reporting:
Capture tradable duration seperately
Modifications since last build (10)
Checked in Donald.sutherland Trunk/SLP/SLPDatabase/CreateScripts/CreateReportDataStoreTables.sql
Merge Branches: Origin=$/Source/RE/Branches/3.1
Version: 2629 [DT-3652]: Reporting:
Capture tradable duration seperately
2010-06-22 15:14:14
Checked in Donald.sutherland Trunk/SLP/SLPDatabase/Change Scripts/ReportDataStore/RpDataStoreDatabaseChangeScript.sql
Merge Branches: Origin=$/Source/RE/Branches/3.1
Version: 2629 [DT-3652]: Reporting:
Capture tradable duration seperate
What should follow is a number of error messsages indicating why the build has failed. The webpage that is failing to parse the log file is "ViewBuildReport.aspx". In order to get an explanation, our development team has to go through the full Build Log xml and search for failures.
The build.config file is attached below:
<project name="TX" queue="Build" queuePriority="1400">
<triggers>
<scheduleTrigger time="21:00" buildCondition="ForceBuild">
<weekDays>
<weekDay>Monday</weekDay>
<weekDay>Tuesday</weekDay>
<weekDay>Wednesday</weekDay>
<weekDay>Thursday</weekDay>
<weekDay>Friday</weekDay>
<weekDay>Saturday</weekDay>
<weekDay>Sunday</weekDay>
</weekDays>
</scheduleTrigger>
</triggers>
<sourcecontrol type="vault" autoGetSource="true" applyLabel="false">
<executable>c:\program files\sourcegear\vault client\vault.exe</executable>
<username>build</username>
<password>*********</password>
<host>niddrie.dataexplorers.net:8080</host>
<repository>DXL Source</repository>
<folder>$/Source/TX/Trunk</folder>
<ssl>false</ssl>
<useWorkingDirectory>true</useWorkingDirectory>
<workingDirectory>D:\Projects\Source\TX\Trunk</workingDirectory>
<cleanCopy>true</cleanCopy>
<timeout units="minutes">30</timeout>
</sourcecontrol>
<tasks>
<msbuild>
<executable>C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe</executable>
<workingDirectory>D:\Projects\Source\TX\Trunk</workingDirectory>
<projectFile>TransactionExplorer.sln</projectFile>
<buildArgs>/noconsolelogger /p:Configuration=Release /v:diag</buildArgs>
<targets>Build</targets>
<timeout>600</timeout>
<logger>C:\Program Files\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MSBuild.dll</logger>
</msbuild>
<exec>
<executable>deploy.bat</executable>
<baseDirectory>D:\Projects\Source\TX\Trunk</baseDirectory>
<buildArgs>D:\Projects\Source\TX\Trunk D:\MasterWebsite\SfsWebroot\Autobuild\TX</buildArgs>
<buildTimeoutSeconds>500</buildTimeoutSeconds>
</exec>
</tasks>
<publishers>
<!-- Mandatory, config file does not work without -->
<xmllogger logDir="C:\Program Files\CruiseControl.NET\server\TX\Artifacts\buildlogs" />
&email;
</publishers>
</project>
As you can see, there is a publisher and the config file hasn't changed since we upgraded to the latest CruiseControl Version. Finally, the necessary log files get generated during the build so it seems to be an issue with the xsd parse or the website itself? The build result files generated are listed below:
C:\Program Files\CruiseControl.NET\server\TX\Artifacts\msbuild-results.xml
C:\Program Files\CruiseControl.NET\server\TX\Artifacts\buildlogs\log20100622234154.xml
Any help to get this working will be greatly appreciated.
Did you check your email publisher? There have been a breaking change with CCNET 1.5. You can read more here :
http://ccnetlive.thoughtworks.com/ccnet/doc/CCNET/CCNet%201.5%20CTP%20Release%20Notes.html
http://ccnetlive.thoughtworks.com/ccnet/doc/CCNET/Email%20Publisher.html
If I understood you well, you said that your build worked fine but since you upgraded it fails, isn't it? How did you do the upgrade? Did you change directory/rights?