Trying to use the commons-vfs sync ant task from Groovy. Solved most of the things, but still having some issues. Here is my groovy script:
#Grapes([
#Grab(group='org.apache.commons', module='commons-vfs2', version='2.0'),
#Grab(group='com.jcraft', module='jsch', version='0.1.53'),
#GrabConfig(systemClassLoader = true)
])
import groovy.xml.NamespaceBuilder
import groovy.io.FileType
localRootDir = 'forUpdateSite'
updateServer = 'some.remote.server.com'
remoteRootDir = '/var/www/directory'
println("Syncing files from ${localRootDir} to ${updateServer} ${remoteRootDir}");
def ant = new AntBuilder()
def vfs = NamespaceBuilder.newInstance(ant, 'antlib:org.apache.commons.vfs2.tasks')
def remoteURI = "sftp://username:{FAKEENCRYPTEDPASSWORD}#${updateServer}${remoteRootDir}"
vfs.sync (destdir: remoteURI) {
src() {
file: localRootDir
}
}
At this point the only thing I am missing is how to specify the local directory and files. This example gives me this stack trace:
Syncing files from forUpdateSite to some.remote.server.com /var/www/directory
Caught: : No source file specified.
: No source file specified.
at org.apache.commons.vfs2.tasks.AbstractSyncTask.addConfiguredSrc(AbstractSyncTask.java:149)
at org.apache.tools.ant.IntrospectionHelper$AddNestedCreator.istore(IntrospectionHelper.java:1469)
at org.apache.tools.ant.IntrospectionHelper$AddNestedCreator.store(IntrospectionHelper.java:1463)
at org.apache.tools.ant.IntrospectionHelper$Creator.store(IntrospectionHelper.java:1370)
at org.apache.tools.ant.UnknownElement.handleChild(UnknownElement.java:582)
at org.apache.tools.ant.UnknownElement.handleChildren(UnknownElement.java:349)
at org.apache.tools.ant.UnknownElement.configure(UnknownElement.java:201)
at org.apache.tools.ant.UnknownElement.maybeConfigure(UnknownElement.java:163)
at syncToUpdateSite.run(syncToUpdateSite.groovy:53)
Turned out to be pretty simple:
#Grapes([
#Grab(group='org.apache.commons', module='commons-vfs2', version='2.0'),
#Grab(group='com.jcraft', module='jsch', version='0.1.53'),
#GrabConfig(systemClassLoader = true)
])
import groovy.xml.NamespaceBuilder
import groovy.io.FileType
localRootDir = 'forUpdateSite'
updateServer = 'some.remote.server.com'
remoteRootDir = '/var/www/directory'
println("Syncing files from ${localRootDir} to ${updateServer} ${remoteRootDir}");
def ant = new AntBuilder()
def vfs = NamespaceBuilder.newInstance(ant, 'antlib:org.apache.commons.vfs2.tasks')
def remoteURI = "sftp://username:{FAKEENCRYPTEDPASSWORD}#${updateServer}${remoteRootDir}"
vfs.sync (destdir: remoteURI,
src: localRootDir)
Note that you have to include the jsch module with #Grab for the sftp URL parsing to work. I was getting the stack trace below before I included that.
Caught: : Badly formed URI "sftp://username:***#some.remote.server.com/var/www/directory".
: Badly formed URI "sftp://username:***#some.remote.server.com/var/www/directory".
at org.apache.commons.vfs2.tasks.AbstractSyncTask.execute(AbstractSyncTask.java:227)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
at syncToUpdateSite.run(syncToUpdateSite.groovy:52)
Caused by: org.apache.commons.vfs2.FileSystemException: Badly formed URI "sftp://username:***#some.remote.server.com/var/www/directory".
at org.apache.commons.vfs2.provider.url.UrlFileProvider.findFile(UrlFileProvider.java:91)
at org.apache.commons.vfs2.impl.DefaultFileSystemManager.resolveFile(DefaultFileSystemManager.java:713)
at org.apache.commons.vfs2.impl.DefaultFileSystemManager.resolveFile(DefaultFileSystemManager.java:649)
at org.apache.commons.vfs2.impl.DefaultFileSystemManager.resolveFile(DefaultFileSystemManager.java:636)
at org.apache.commons.vfs2.tasks.VfsTask.resolveFile(VfsTask.java:56)
at org.apache.commons.vfs2.tasks.AbstractSyncTask.handleFiles(AbstractSyncTask.java:247)
at org.apache.commons.vfs2.tasks.AbstractSyncTask.execute(AbstractSyncTask.java:218)
... 3 more
Caused by: java.net.MalformedURLException: unknown protocol: sftp
at org.apache.commons.vfs2.provider.url.UrlFileProvider.findFile(UrlFileProvider.java:72)
... 9 more
Related
Here is simple request I try to do and watch response
def httpReq = new HTTPBuilder("http://${url}")
httpReq.request(Method.GET, ContentType.JSON) {
response.success = { resp ->
println("Ok " + resp.status.toString())
}
response.failure = { resp ->
println("Not ok" + resp.status.toString())
}
This returns an Error:
java.lang.ClassNotFoundException: org.apache.commons.collections.iterators.ArrayIterator
I think that ArrayIterator defined in jdk. I added manually org.apache.commons:commons-collections4:4.4 but it doesn't help.
TL;DR
Don't waste your time by gathering deps. Use a build tool like Gradle
or Maven - or use Groovys Grapes if only a script is needed and Groovy
is installed (or easily installable) on your target.
Using grape
You have to pick up all the transitive dependencies (this means the correct packages with the correct versions). E.g. with #Grab:
#Grab('org.codehaus.groovy.modules.http-builder:http-builder:0.7.1')
import groovyx.net.http.HTTPBuilder
def http = new HTTPBuilder('http://www.google.com')
def html = http.get( path : '/search', query : [q:'Groovy'] )
If you really want to gather all the deps manually grape can also
help. It can tell you, what jars are needed:
% grape resolve org.codehaus.groovy.modules.http-builder http-builder 0.7.1
$HOME/.groovy/grapes/org.codehaus.groovy.modules.http-builder/http-builder/jars/http-builder-0.7.1.jar
$HOME/.groovy/grapes/org.apache.httpcomponents/httpclient/jars/httpclient-4.2.1.jar
$HOME/.groovy/grapes/org.apache.httpcomponents/httpcore/jars/httpcore-4.2.1.jar
$HOME/.groovy/grapes/commons-logging/commons-logging/jars/commons-logging-1.1.1.jar
$HOME/.groovy/grapes/commons-codec/commons-codec/jars/commons-codec-1.6.jar
$HOME/.groovy/grapes/net.sf.json-lib/json-lib/jars/json-lib-2.3-jdk15.jar
$HOME/.groovy/grapes/commons-beanutils/commons-beanutils/jars/commons-beanutils-1.8.0.jar
$HOME/.groovy/grapes/commons-collections/commons-collections/jars/commons-collections-3.2.1.jar
$HOME/.groovy/grapes/commons-lang/commons-lang/jars/commons-lang-2.4.jar
$HOME/.groovy/grapes/net.sf.ezmorph/ezmorph/jars/ezmorph-1.0.6.jar
$HOME/.groovy/grapes/net.sourceforge.nekohtml/nekohtml/jars/nekohtml-1.9.16.jar
$HOME/.groovy/grapes/xerces/xercesImpl/jars/xercesImpl-2.9.1.jar
$HOME/.groovy/grapes/xml-apis/xml-apis/jars/xml-apis-1.3.04.jar
$HOME/.groovy/grapes/xml-resolver/xml-resolver/jars/xml-resolver-1.2.jar
From this list you can build up your own classpath to pass to groovy and
work without grape. E.g.:
% cat no-grape.groovy
import groovyx.net.http.HTTPBuilder
def http = new HTTPBuilder('http://www.google.com')
def html = http.get( path : '/search', query : [q:'Groovy'] )
% groovy -cp `grape resolve org.codehaus.groovy.modules.http-builder http-builder 0.7.1 | paste -s -d:` no-grape.groovy
...
I'm writing a script in Groovy and I would like someone to be able to execute it simply by running ./myscript.groovy. However, this script requires a 3rd party library (MySQL JDBC), and I don't know of any way to provide this to the script other than via a -classpath or -cp argument, e.g.
`./monitor-vouchers.groovy -cp /path/to/mysql-lib.jar`
For reasons I won't go into here, it's not actually possible to provide the JAR location to the script using the -classpath/-cp argument. Is there some way that I can load the JAR from within the script itself? I tried using #Grab
import groovy.sql.Sql
#Grab(group='mysql', module='mysql-connector-java', version='5.1.19')
def getConnection() {
def dbUrl = 'jdbc:mysql://database1.c5vveqm7rqgx.eu-west-1.rds.amazonaws.com:3306/vouchers_prod'
def dbUser = 'pucaroot'
def dbPassword = 'password'
def driverClass = "com.mysql.jdbc.Driver"
return Sql.newInstance(dbUrl, dbUser, dbPassword, driverClass)
}
getConnection().class
But this causes the following error:
Caught: java.sql.SQLException: No suitable driver
java.sql.SQLException: No suitable driver
at monitor-vouchers.getConnection(monitor-vouchers.groovy:13)
at monitor-vouchers.run(monitor-vouchers.groovy:17)
Is there a way I can execute this script using just ./monitor-vouchers.groovy
You should be able to do:
import groovy.sql.Sql
#GrabConfig(systemClassLoader=true)
#Grab('mysql:mysql-connector-java:5.1.19')
def getConnection() {
def dbUrl = 'jdbc:mysql://database1.c5vveqm7rqgx.eu-west-1.rds.amazonaws.com:3306/vouchers_prod'
def dbUser = 'pucaroot'
def dbPassword = 'bigsecret'
def driverClass = "com.mysql.jdbc.Driver"
return Sql.newInstance(dbUrl, dbUser, dbPassword, driverClass)
}
getConnection().class
Two more options:
Put the jar in ${user.home}/.groovy/lib
If the jar is in a known location, use this code to load it into the current class loader:
this.class.classLoader.rootLoader.addURL( new URL() )
I want to play around with NekoHtml, in Groovy. I thought of adding it via Grape.
I tried this way :
#GrabResolver(root="http://net.sourceforge.nekohtml/nekohtml")
in my Groovy code.
But it is throwing an error like this :
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
/home/anto/Groovy/webScrape/webFetch.groovy: 3: unexpected token: # line 3, column 1.
The NekoHtml can be found in Maven over here.
Edit:
Now I have a code like this :
#Grab('net.sourceforge.nekohtml:nekohtml:1.9.15')
import org.cyberneko.html.parsers.SAXParser
def url = 'http://java.sun.com'
def html = new XmlSlurper(new org.cyberneko.html.parsers.SAXParser()).parse(url)
def bolded = html.'**'.findAll{ it.name() == 'B' }
def out = bolded.A*.text().collect{ it.trim() }
out.removeAll([''])
out[2..5].each{ println it }
which throws the error like this :
Caught: java.lang.NoClassDefFoundError: org/apache/xerces/parsers/AbstractSAXParser
java.lang.NoClassDefFoundError: org/apache/xerces/parsers/AbstractSAXParser
Caused by: java.lang.ClassNotFoundException: org.apache.xerces.parsers.AbstractSAXParser
Couldn't able to figure out what this error states.
Thanks in advance.
Have you tried:
#Grab('net.sourceforge.nekohtml:nekohtml:1.9.15')
Then it should resolve from maven
Through a groovy teststep in soapUI i want all request and response files to be stored in a local directory with system date.
The groovy teststep in soapUI:
def name = context.expand( '${Input#TG}' )
def locatie = context.expand( '${#TestCase#locatie}' )
def createFolder() {
date = new Date()
dateFormat = new java.text.SimpleDateFormat('ddMMyyyy')
shortDate = dateFormat.format(date)
outputFolder = locatie+shortDate
createFolder = new File(outputFolder)
createFolder.mkdir()
}
def getResponseFilename(name) {
respFilename = createFolder()+"_"+name+"_response.xml"
}
def getRequestFilename(locatie,name) {
reqFilename = createFolder()+"_"+ name+"_request.xml"
}
def file = new PrintWriter (getResponseFilename(name))
def response = testRunner.testCase.testSteps
["CheckAdres"].testRequest.response.contentAsString
file.println(response)
file.flush()
file.close()
def file2 = new PrintWriter (getRequestFilename(name))
def request = context.expand('${CheckAdres#Request}')
file2.println(request)
file2.flush()
file2.close()
I get the following error:
Tue Jun 14 12:47:24 CEST 2011:**ERROR:groovy.lang.MissingPropertyException: No such property: locatie for class: Script78**
groovy.lang.MissingPropertyException: No such property: locatie for class: Script78
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:49)
at org.codehaus.groovy.runtime.callsite.PogoGetPropertySite.getProperty(PogoGetPropertySite.java:49)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:241)
at Script78.createFolder(Script78.groovy:8)
at Script78$createFolder.callCurrent(Unknown Source)
at Script78.getResponseFilename(Script78.groovy:14)
at Script78$getResponseFilename.callCurrent(Unknown Source)
at Script78.run(Script78.groovy:21)
at com.eviware.soapui.support.scripting.groovy.SoapUIGroovyScriptEngine.run(SoapUIGroovyScriptEngine.java:93)
at com.eviware.soapui.support.scripting.groovy.SoapUIProGroovyScriptEngineFactory$SoapUIProGroovyScriptEngine.run(SourceFile:51)
at com.eviware.soapui.impl.wsdl.teststeps.WsdlGroovyScriptTestStep.run(WsdlGroovyScriptTestStep.java:148)
at com.eviware.soapui.impl.wsdl.panels.teststeps.GroovyScriptStepDesktopPanel$RunAction$1.run(GroovyScriptStepDesktopPanel.java:274)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
There are several ways of doing this. One would be creating a Groovy test step with the following script:
def myOutFile = "C:/Temp/MyOutDir/response.xml"
def response = context.expand( '${MyTestRequest#Response}' )
def f = new File(myOutFile)
f.write(response, "UTF-8")
Try to use SoapUI's tools to select the value of whatever you want.
Right click on the groovy editing area, choose Get Data --> your test suite --> your test case --> your test step --> response. This will get you the entire response. You can also dive deeper into the response with this method.
There is a shorter syntax. Logic is similar what #robert Shared
def response=context.expand('${TestRequest#RawRequest}')
new File("c:/testpath/input.xml").write(response)
if you want to reduce it to just one line
new File("c:/testpath/input.xml").write(context.expand('${TestRequest#RawRequest}')
You can replace RawRequest with whatever you want to save
Request or Response
RawRequest is used when you want data replacing the variables used in request
Check out the answer by McDonald. Best way to save and shoot request.
http://www.loadui.org/forum/viewtopic.php?f=5&t=16354#p38935
More useful if we should save an error in Response:
import com.eviware.soapui.support.XmlHolder
import java.text.MessageFormat
import org.apache.commons.lang.ObjectUtils
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
def retrieve = groovyUtils.getXmlHolder("MyTestRequest#Response" )
if (!ObjectUtils.equals(retrieve.getNodeValue("//*:xpath"), "string")){
def currentTime = System.currentTimeMillis()
def fullFilePath = context.expand('${projectDir}') + File.separator + "Fail-"+currentTime+".xml"
def reportFile = new File(fullFilePath)
if (!reportFile.exists())
{
reportFile.createNewFile()
reportFile.append((Object)retrieve.getPrettyXml(), 'UTF-8')
}
}
This is related to . I'm trying to dynamically add the maven-ant-tasks jars with Grape, simulating this:
<taskdef uri="antlib:org.apache.maven.artifact.ant"
resource="org/apache/maven/artifact/ant/antlib.xml"
classpathref="ant.classpath" />
I've tried to use Grape.grab() to make maven-ant-tasks available to AntBuilder like this:
import groovy.grape.Grape
println "grab..."
Grape.grab(group:'ant', module:'ant', version:'1.7.0', classLoader:this.class.classLoader.rootLoader)
Grape.grab(group: 'org.apache.maven', module: 'maven-ant-tasks', version: '2.0.9')
println "ant taskdef..."
def ant = new AntBuilder()
ant.taskdef (resource: "org/apache/maven/artifact/ant/antlib.xml" )
but that doesn't work because Grape adds the modules to a different ClassLoader from the one that ANT engine is using. So, I took the advice from this AntBuilder classpath question and made Grape use the root ClassLoader:
import groovy.grape.Grape
println "grab..."
Grape.grab(group:'ant', module:'ant', version:'1.7.0', classLoader:this.class.classLoader.rootLoader)
Grape.grab(group: 'org.apache.maven', module: 'maven-ant-tasks', version: '2.0.9', classLoader: this.class.classLoader.rootLoader)
println "ant taskdef..."
def ant = new AntBuilder()
ant.taskdef (resource: "org/apache/maven/artifact/ant/antlib.xml" )
Now it throws a LinkageError:
Caught: : java.lang.LinkageError: loader constraint violation: when resolving overridden method "org.apache.tools.ant.helper.ProjectHelper2$RootHandler.setDocumentLocator(Lorg/xml/sax/Locator;)V" the class loader (instance of org/codehaus/groovy/tools/RootLoader) of the current class, org/apache/tools/ant/helper/ProjectHelper2$RootHandler, and its superclass loader (instance of <bootloader>), have different Class objects for the type org/xml/sax/Locator used in the signature
at test.mavenanttasks.run(mavenanttasks.groovy:11)
Any hints on getting this to work? Or, is the whole thing a bad idea?
I found this: http://groovy.codehaus.org/Using+Ant+Libraries+with+AntBuilder
First, put maven-ant-tasks in the root classloader with:
#Grapes([
#Grab(group = 'org.apache.maven', module = 'maven-ant-tasks', version = '2.1.3'),
#GrabConfig(systemClassLoader = true)
])
Alternatively, for older versions of Groovy:
Grape.grab(group: 'org.apache.maven', module: 'maven-ant-tasks', version: '2.1.3', classLoader: this.class.classLoader.rootLoader)
The Maven ANT tasks are an 'AntLib', and they can be loaded like this:
import groovy.xml.NamespaceBuilder
def ant = new AntBuilder()
def mvn = NamespaceBuilder.newInstance(ant, 'antlib:org.apache.maven.artifact.ant')
We can create ant path(classpath) using java.net.URLClassLoader or it's subclass
eg:
<!-- language: groovy -->
#Grapes([
#Grab(group='org.jacoco', module='org.jacoco.ant', version= '0.7.4.201502262128'),
#Grab(group='org.jacoco', module='org.jacoco.core', version= '0.7.4.201502262128'),
#Grab('org.jacoco:org.jacoco.report:0.7.4.201502262128'),
])
class Tool {
def dump(args){
println "do dump...:$args"
println "DumpTask:"+org.jacoco.ant.DumpTask.classLoader;
def ant = new AntBuilder();
def path1 = ant.path{
org.jacoco.ant.DumpTask.classLoader.getURLs().each {
ant.pathelement(location:it.getFile())
}
}
println "path11:$path1";
// classname way
// ant.taskdef(name:"dump",classname:"org.jacoco.ant.DumpTask",classpath:path1);
// ant.dump(args);
//namespace way
ant.taskdef(uri:'antlib:org.jacoco.ant',resource:'org/jacoco/ant/antlib.xml',classpath:path1);
def jacoco=groovy.xml.NamespaceBuilder.newInstance(ant, 'antlib:org.jacoco.ant')
jacoco.dump(args);
}
}