Apologies for the newbie question, but how do you install HTTPBuilder for Groovy?
I've added the http-builder-0.7.jar, http-builder-0.7-source.jar, and http-builder-0.7-javadoc.jar to GROOVY_HOME/lib.
Is there anything else I need to do? The HTTPBuilder website isn't clear.
Code run from GroovyConsole:
import groovy.grape.Grape
Grape.grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.7' )
def http = new groovyx.net.http.HTTPBuilder('http://www.codehaus.org')
I get this in response:
groovy.lang.MissingMethodException: No signature of method: static groovy.grape.Grape.grab() is applicable for argument types: (java.lang.String, java.lang.String, java.lang.String) values: [org.codehaus.groovy.modules.http-builder, http-builder, 0.7]
Possible solutions: grab(java.lang.String), grep(), grab(java.util.Map), grab(java.util.Map, [Ljava.util.Map;), wait(), dump()
EDIT 2:
#Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.7' )
def http = new groovyx.net.http.HTTPBuilder('http://www.codehaus.org')
Response:
java.lang.NoClassDefFoundError: org/apache/http/client/methods/HttpRequestBase
at ConsoleScript6.run(ConsoleScript6:4)
Caused by: java.lang.ClassNotFoundException: org.apache.http.client.methods.HttpRequestBase
... 1 more
The following example works for me out of the box:
#Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.7' )
def http = new groovyx.net.http.HTTPBuilder('http://www.codehaus.org')
println http
You need to remove any of the dependency jars you added directly to GROOVY_HOME\lib. Manually adding the jars there could create conflicts and cause these types of errors. Check to see if you have manually added the HttpClient libraries to the lib, remove them as well and try again.
EDIT: When using IntelliJ, I have been able to reproduce this behavior once. I already had a single #Grab annotation added to my Groovy script. When I added a second, it didn't seem to download or import the new library.
First of all, if you add a second #Grab, you need to wrap it in the #Grapes annotation like the following (my first mistake):
#Grapes([
#Grab(group='org.codehaus.gpars', module='gpars', version='1.2.1'),
#Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.7.1')
])
After that, I found my solution here: Intellij IDEA not importing dependencies from #Grab in Groovy project, which explains than when using IntelliJ and you encounter this issue, try placing your cursor next to the #Grapes annotation and selecting Alt+Enter then choose the 'Grab the Artifacts' option.
Related
I am trying to create a simple Birt report following this example using Groovy instead. I'm not certain if it's even possible to design reports with Groovy but I haven't been able to find a solution.
From my understanding I don't believe I need to set BIRT_HOME after version 3.7. Regardless I receive the same error with or without setting BIRT_HOME. For some reason createFactoryObject returns null so I cannot use the createDesignEngine function. I'm not sure if I need to Grab another runtime version or if I'm missing other imports because I'm using Groovy. Any ideas are appreciated.
import java.io.IOException;
#Grab(group='org.eclipse.birt.runtime', module='org.eclipse.birt.runtime',
version='4.5.0a')
import org.eclipse.birt.core.framework.Platform;
import org.eclipse.birt.report.model.api.CellHandle;
import org.eclipse.birt.report.model.api.DesignConfig;
import org.eclipse.birt.report.model.api.DesignElementHandle;
import org.eclipse.birt.report.model.api.DesignEngine;
import org.eclipse.birt.report.model.api.ElementFactory;
import org.eclipse.birt.report.model.api.GridHandle;
import org.eclipse.birt.report.model.api.IDesignEngine;
import org.eclipse.birt.report.model.api.IDesignEngineFactory;
import org.eclipse.birt.report.model.api.ImageHandle;
import org.eclipse.birt.report.model.api.LabelHandle;
import org.eclipse.birt.report.model.api.ReportDesignHandle;
import org.eclipse.birt.report.model.api.RowHandle;
import org.eclipse.birt.report.model.api.SessionHandle;
import org.eclipse.birt.report.model.api.activity.SemanticException;
import com.ibm.icu.util.ULocale;
/**
* Simple BIRT Design Engine API (DEAPI) demo.
*/
// Create a session handle. This is used to manage all open designs.
// Your app need create the session only once.
//Configure the Engine and start the Platform
DesignConfig config = new DesignConfig( );
//config.setProperty("BIRT_HOME", "C:\\birtruntime\\birt-runtime-4_5_0\\ReportEngine");
IDesignEngine engine = null;
try{
Platform.startup( config );
IDesignEngineFactory factory = (IDesignEngineFactory)
Platform.createFactoryObject( IDesignEngineFactory.EXTENSION_DESIGN_ENGINE_FACTORY );
engine = factory.createDesignEngine( config );
}catch( Exception ex){
ex.printStackTrace();
}
This is the error I receive
java.lang.NullPointerException: Cannot invoke method createDesignEngine() on null object
at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:91)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:47)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.NullCallSite.call(NullCallSite.java:34)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:128)
at sample.run(sample.groovy:42)
at groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:264)
at groovy.lang.GroovyShell.run(GroovyShell.java:377)
at groovy.lang.GroovyShell.run(GroovyShell.java:366)
at groovy.ui.GroovyMain.processOnce(GroovyMain.java:589)
at groovy.ui.GroovyMain.run(GroovyMain.java:332)
at groovy.ui.GroovyMain.access$1400(GroovyMain.java:69)
at groovy.ui.GroovyMain$GroovyCommand.process(GroovyMain.java:291)
at groovy.ui.GroovyMain.processArgs(GroovyMain.java:134)
at groovy.ui.GroovyMain.main(GroovyMain.java:116)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:114)
at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:136)
Caught: java.lang.NullPointerException: Cannot invoke method newSessionHandle() on null object
java.lang.NullPointerException: Cannot invoke method newSessionHandle() on null object
at sample.run(sample.groovy:49)
Evgeny recommended to place the factory creation on a single line. I did not realize it was on 2 lines when I posted it here. Regardless it was on a single line in my source code so that was not the issue.
I did not figure out how to get this piece of code to work with the groovy grab command but I did figure it out using the classpath option. First I downloaded the runtime engine on the eclipse website. It would be the zip file under the Report Engine section. You might be able to use a newer version but I got it to work with 4.5.0.
Unzip this folder somewhere and in the ReportEngine\lib folder copy all the org.eclipse jars along with the flute, com.ibm.icu, and org.mozilla.javascript jars into a separate folder like C:\birtJars. You might be able to use even less jars but I didn't want to spend the time to figure out which ones weren't needed. All I know is if I added ReportEngin\lib to the classpath there would be a linkage error from what I assume were class names that matched some java classes.
Now to get the script to run in the command line you can use
groovy -cp "C:\birtJars\*;." myscript.groovy
What I did not know at first was that if you used -cp after your groovy script then the given classpath will not be used
I am trying to use org.xhtmlrenderer:core-renderer:R8pre2 in a groovy script, but I get a Linkage error:
Caught: java.lang.LinkageError: loader constraint violation in interface
itable initialization: when resolving method
"org.apache.xerces.dom.NodeImpl.getOwnerDocument()Lorg/w3c/dom/Document;"
the class loader (instance of org/codehaus/groovy/tools/RootLoader) of the
current class, org/apache/xerces/dom/NodeImpl, and the class loader (instance of
<bootloader>) for interface org/w3c/dom/Node have different Class objects for
the type getOwnerDocument used in the signature
I've already googled a lot and found a lot of answer like these:
Dealing with "Xerces hell" in Java/Maven?
XercesImpl in conflict with JavaSE 6's internal xerces implementation. Both are needed... what can be done?
So, one solution could be to use javas endorsed mechanism to resolve the conflict, but I would like to make my script independent from such a "workaround". The script should run out of the box.
Next thing I was giving a try was to exclude the right dependency like this
#Grapes([
#Grab('org.xhtmlrenderer:core-renderer:R8pre2'),
#GrabExclude('xml-apis:xml-apis')
])
but didn't succeed...
Any ideas?
PS: here is the script which creates the error:
#Grapes([
#Grab('org.xhtmlrenderer:core-renderer:R8pre2'),
])
import org.w3c.dom.Document
import javax.xml.parsers.DocumentBuilder
import javax.xml.parsers.DocumentBuilderFactory
def dbf = DocumentBuilderFactory.newInstance()
DocumentBuilder builder = dbf.newDocumentBuilder()
Document doc = builder.parse(new ByteArrayInputStream("<html></html>".getBytes()))
Thanx to #dmahapatro, I checked my configuration and found that I dropped some jars in {usrhome}/.groovy a long time ago. Removed these and now everything work like a charm...
I am trying to use this method without a closure
def copyAndReplaceText(source, dest, targetText, replaceText){
dest.write(source.text.replaceAll(targetText, replaceText))
}
def source = new File('C:/geretd/resumebak.txt') //Hello World
def dest = new File('C:/geretd/resume.txt') //blank
copyAndReplaceText(source, dest){
it.replaceAll('Visa', 'Passport!!!!')
}
but when I run it I get the following error:
groovy.lang.MissingMethodException: No signature of method: ConsoleScript3.copyAndReplaceText() is applicable for argument types: (java.io.File, java.io.File, ConsoleScript3$_run_closure1) values: [C:\geretd\resumebak.txt, C:\geretd\resume.txt, ...]
Possible solutions: copyAndReplaceText(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:55)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:78)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:149)
What am I doing wrong?
Because you are passing three arguments to a four arguments method. Also, you are not using the passed closure.
If you want to specify the operations to be made on top of the source contents, then use a closure. It would be something like this:
def copyAndReplaceText(source, dest, closure){
dest.write(closure( source.text ))
}
// And you can keep your usage as:
copyAndReplaceText(source, dest){
it.replaceAll('Visa', 'Passport!!!!')
}
If you will always swap strings, pass both, as your method signature already states:
def copyAndReplaceText(source, dest, targetText, replaceText){
dest.write(source.text.replaceAll(targetText, replaceText))
}
copyAndReplaceText(source, dest, 'Visa', 'Passport!!!!')
To help other bug-hunters. I had this error because the function didn't exist.
I had a spelling error.
In my case it was simply that I had a variable named the same as a function.
Example:
def cleanCache = functionReturningABoolean()
if( cleanCache ){
echo "Clean cache option is true, do not uninstall previous features / urls"
uninstallCmd = ""
// and we call the cleanCache method
cleanCache(userId, serverName)
}
...
and later in my code I have the function:
def cleanCache(user, server){
//some operations to the server
}
Apparently the Groovy language does not support this (but other languages like Java does).
I just renamed my function to executeCleanCache and it works perfectly (or you can also rename your variable whatever option you prefer).
You can also get this error if the objects you're passing to the method are out of order. In other words say your method takes, in order, a string, an integer, and a date. If you pass a date, then a string, then an integer you will get the same error message.
This may also be because you might have given classname with all letters in lowercase something which groovy (know of version 2.5.0) does not support.
class name - User is accepted but user is not.
In my case problem is I commented firebase dependency in build.gradle file but still using this in debug build type:
firebaseCrashlytics {
mappingFileUploadEnabled true
}
Just make it commented to make it work.
This was one of the major issues for the ionic/android app
Please follow the below steps.
Remove/Delete node-module from root folder
npm uninstall cordova-android
npm install cordova-android#10.1.1
Now remove android platform using: ionic cordova rm platform android
Now add platform : ionic cordova platform add android
Build Android Project : ionic cordova build android
Problem will be resolved
Also obtained by calling an instance method from a static method.
Solution. Add missing static keyword to the instance method
Another one - If you try to call a super method / constructor that is marked private.
If you're extending a class make sure everything your child class touches is marked as protected or public.
When I try to run the code below from Eclipse/STS I get the following exception:
Caught: groovy.lang.MissingMethodException: No signature of method:
groovy.json.JsonBuilder.message() is applicable for argument types:
(ie.makalu.scripts.TestJsonBuilder$_run_closure1) values:
[ie.makalu.scripts.TestJsonBuilder$_run_closure1#d05c13]
but when I run it from the shell it works fine. Can anyone suggest why that may be?
I've tried this in Groovy 1.8.6 and Groovy 2.0 using STS version 2.9.2
package ie.makalu.scripts
import groovy.json.JsonBuilder
def json = new JsonBuilder()
json.message {
header {
from('mrhaki') // parenthesis are optional
to 'Groovy Users', 'Java Users'
}
body "Check out Groovy's gr8 JSON support."
}
println json.toString()
I would advise against using Eclipse STS - it seems to me that too many people are constantly having issues with it. Instead I would install standard Eclipse or Eclipse for Java Development (anything from a eclipse community but not a specialized STS stuff) and install Groovy (and if you need Grails) plugin on top. It works much better and you are free to install any additional plugin that might not be working under STS version.
Also I would suggest to try IntelliJ, it has nice integration with Groovy (and Grails).
I have this at the beginning of a class:
#Grab(group = 'org.ccil.cowan.tagsoup', module = 'tagsoup', version = '1.2')
class MyClass{...
I'm trying to unit test this class, but whenever I try to run JUnit 4 tests, I get this error:
Caused by: java.lang.RuntimeException: No suitable ClassLoader found for grab
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:77)
at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:102)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:52)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:190)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:198)
at groovy.grape.GrapeIvy.chooseClassLoader(GrapeIvy.groovy:163)
at groovy.grape.GrapeIvy$chooseClassLoader.callCurrent(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:44)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:149)
at groovy.grape.GrapeIvy.grab(GrapeIvy.groovy:227)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSite.invoke(PogoMetaMethodSite.java:225)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:51)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:44)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:153)
at groovy.grape.GrapeIvy.grab(GrapeIvy.groovy:216)
at groovy.grape.Grape.grab(Grape.java:131)
at groovy.grape.Grape$grab.callStatic(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:165)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:173)
at ammoscanner.AmmoScanner.<clinit>(AmmoScanner.groovy)
... 30 more
Any ideas? I'm using groovy 1.7.5
The Problem
Looking at the source code, this exception is thrown whenever the supplied ClassLoader's name (or it's superclasses) is not groovy.lang.GroovyClassLoader or org.codehaus.groovy.tools.RootLoader. i.e. The target classloader must be an instance of the aforementioned classes (a bit restrictive IMHO).
A Solution
Currently I don't know how to configure a specific classloader using #Grape/#Grab/#GrabConfig annotations. The closest would be to use #GrabConfig(systemClassLoader=true), and ensure the System classloader is an instance of one of the above ClassLoader classes.
If anyone does know, please let me know (and I'll update this answer).
A Workaround
The following code will programmatically download your Grapes, and load them into the supplied GroovyClassLoader (admittedly, not quite what you want).
def loadGrapes(){
ClassLoader classLoader = new groovy.lang.GroovyClassLoader()
Map[] grapez = [[group : 'org.ccil.cowan.tagsoup', module : 'tagsoup', version : '1.2']]
Grape.grab(classLoader: classLoader, grapez)
println "Class: " + classLoader.loadClass('org.ccil.cowan.tagsoup.jaxp.SAXParserImpl')
}
Using #Grab makes code untestable, at least as of 01/26/2011.
Solution that worked for me (both for running tests for scripts using #Grab in IntelliJ and via Maven):
Reference the dependencies used via #Grab in your Maven pom.xml file (this is useful anyway for better coding experience):
E.g. I have the following #Grab in my Groovy script:
#Grab(group='info.picocli', module='picocli', version='4.6.1')
So I add the following Maven dependency:
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli</artifactId>
<version>4.6.1</version>
</dependency>
Add an optional dependency on ivy in your Maven pom.xml file (needed to handle #Grab properly in your IDE):
<dependency>
<groupId>org.apache.ivy</groupId>
<artifactId>ivy</artifactId>
<version>${ivy.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
In your test code, set groovy.grape.enable system property to false. This is the main and crucial part of the solution - it disables #Grab annotation processing for the script, but remember we already have those dependencies referenced in our Maven pom.xml file:
static {
System.setProperty("groovy.grape.enable", "false")
}
#Test
void test() {
MainScript.call()
}
The downside of the solution is that you have to duplicate your dependencies in #Grab and Maven pom.xml file but again, if you develop a Groovy script you oftentimes already do so to improve your coding experience (get better code highlights etc).
I assume you've tried adding
#GrabConfig(systemClassLoader=true)
like so:
#Grapes([
#Grab(group = 'org.ccil.cowan.tagsoup', module = 'tagsoup', version = '1.2'),
#GrabConfig( systemClassLoader=true )
])
class MyClass{...
If you are not using systemClassLoader=true then it seems your IDE is not rrunning the code with a groovy compiler, you can check that with a simple groovy class that outputs the class name of its classloader. I would guess it tries to compile the groovy classes and run them with a non-groovy classloader.
See also this answer to General error during conversion: No suitable ClassLoader found for grab. Also this blog post explains more about running pre-compiled groovy classes with the stock classloader.
Add the plugin snapshot update site for Kepler.
This seems to solve the "..no suitable classloader problem". Unfortunately, I still had to add the grape repo to the classpath for the project after this.
There's one more solution for testing a class with #Grab annotation:
Extract an interface from this class.
Create another class which implements its interface. Move the #Grab annotation to this class. Then make this class a simple wrapper, which just passes all the messages to the original class.
Run the tests against your original class.
Whenever you need to have a version #Grab, use the wrapper.
There is a solution to this!
You can use Groovy's metaprogramming to override the methods responsible for determining if the class loader is an instance of groovy.lang.GroovyClassLoader or org.codehaus.groovy.tools.RootLoader.
Because of this Groovy bug, you cannot override the private methods using metaprogramming, otherwise you could go ahead and change the isValidTargetClassLoaderClass method by doing this:
GrapeIvy.metaClass.isValidTargetClassLoaderClass = { Class loaderClass ->
return (loaderClass != null)
}
However, isValidTargetClassLoaderClass is called by isValidTargetClassLoader (another private method), which is called by chooseClassLoader, which is a public method, which can be overridden using metaprogramming:
GrapeIvy.metaClass.chooseClassLoader = { Map args ->
def loader = args.classLoader
if (loader?.class == null) {
loader = (args.refObject?.class
?: ReflectionUtils.getCallingClass(args.calleeDepth?:1)
)?.classLoader
while (loader && loader?.class == null) {
loader = loader.parent
}
if (loader?.class == null) {
throw new RuntimeException("No suitable ClassLoader found for grab")
}
}
return loader
}
All I did was replace any calls to !isValidTargetClassLoader with loader?.class == null.
Now, I am using Spock, so I put this code in my setupSpec method in my test class. However if you are using JUnit, I would imagine it would want to go in the method annotated with #BeforeClass.
Here is an example of it working with Spock (notice IntelliJ showing it about to return a class loader that would normally throw an exception: