Details
-
Type:
Improvement
-
Status:
Closed
-
Priority:
Major
-
Resolution: Fixed
-
Affects Version/s: 1.7-beta-1
-
Fix Version/s: 1.7-beta-2
-
Component/s: Grape
-
Labels:None
-
Number of attachments :
Description
The current @Grab and @Grapes annotations provide a simplified way to bring in dependencies but there are some limitations:
- you get all transitive dependencies
- there is no way to exclude a particular unwanted transitive dependency
- you sometimes don't get the right classloader
We should consider enhancing support to overcome these limitations.
Attachments
Issue Links
| This issue relates to: | ||||
| GROOVY-3583 | Grape issues |
|
|
|
Attached patch covers the following cases:
Ex1 will 'grab' htmlunit but no transitive dependencies.
It fails after not finding 'httpclient'
Ex2 will 'grab' htmlunit and transitive dependencies but not xerces.
It fails after not finding 'xerces'. At the moment, the exclude is
kind of global. This might need some more work.
@Grapes([ @Grab('net.sourceforge.htmlunit:htmlunit:2.6'), @GrabExclude('xerces:xercesImpl') ]) import com.gargoylesoftware.htmlunit.WebClient def client = new WebClient() try { def page = client.getPage('http://www.google.com') assert 'Google' == page.titleText println 'done without error' } catch(java.lang.NoClassDefFoundError ncdfe) { assert ncdfe.message.contains('org/apache/xerces') println 'done with expected error' }Ex3 will 'grab' mysql jars and add via system classloader
@Grapes([ @Grab('mysql:mysql-connector-java:5.1.6'), @GrabConfig(systemClassLoader=true) ]) import groovy.sql.Sql def sql=Sql.newInstance("jdbc:mysql://localhost/test", "manager", "password", "com.mysql.jdbc.Driver") println sql.firstRow('SELECT * FROM INFORMATION_SCHEMA.COLUMNS')Ex4 will 'grab' xstream and xpp3 jars and add via system classloader
and also points the context class loader to the current script class loader.
(In some ways this last bit has nothing to do with Grapes but it still
occurs commonly enough to tack on a partial solution here I think).
@Grapes([ @Grab('com.thoughtworks.xstream:xstream:1.3.1'), @Grab('xpp3:xpp3_min:1.1.4c'), @GrabConfig(systemClassLoader=true, initContextClassLoader=true) ]) import com.thoughtworks.xstream.* class Staff { String firstname, lastname, position } def xstream = new XStream() def john1 = new Staff(firstname:'John', lastname:'Connor', position:'Resistance Leader') // write out to XML file new File("john.xml").withOutputStream { out -> xstream.toXML(john1, out) } // now read back in def john2 new File("john.xml").withInputStream { ins -> john2 = xstream.fromXML(ins) } println john2.dump()@Grapes([ @Grab('net.sourceforge.htmlunit:htmlunit:2.6'), @GrabExclude('xerces:xercesImpl') ]) import com.gargoylesoftware.htmlunit.WebClient def client = new WebClient() try { def page = client.getPage('http://www.google.com') assert 'Google' == page.titleText println 'done without error' } catch(java.lang.NoClassDefFoundError ncdfe) { assert ncdfe.message.contains('org/apache/xerces') println 'done with expected error' }@Grapes([ @Grab('mysql:mysql-connector-java:5.1.6'), @GrabConfig(systemClassLoader=true) ]) import groovy.sql.Sql def sql=Sql.newInstance("jdbc:mysql://localhost/test", "manager", "password", "com.mysql.jdbc.Driver") println sql.firstRow('SELECT * FROM INFORMATION_SCHEMA.COLUMNS')@Grapes([ @Grab('com.thoughtworks.xstream:xstream:1.3.1'), @Grab('xpp3:xpp3_min:1.1.4c'), @GrabConfig(systemClassLoader=true, initContextClassLoader=true) ]) import com.thoughtworks.xstream.* class Staff { String firstname, lastname, position } def xstream = new XStream() def john1 = new Staff(firstname:'John', lastname:'Connor', position:'Resistance Leader') // write out to XML file new File("john.xml").withOutputStream { out -> xstream.toXML(john1, out) } // now read back in def john2 new File("john.xml").withInputStream { ins -> john2 = xstream.fromXML(ins) } println john2.dump()