Error: md5sum: stat '>': No such file or directory - linux

I am trying to write a program that runs the Linux commands using Scala.
I have written a snippet of code to run the functionalities of md5sum command.
Code snippet
object Test extends App {
import sys.process._
case class md5sum_builder private(i: Seq[String]) {
println(i)
protected def this() = this(Seq(""))
def optionCheck() = new md5sum_builder(i :+ "-c")
def files(file: String) = new md5sum_builder(i :+ file)
def hashFile(hashfile: String) = new md5sum_builder(i :+ hashfile)
def assignment(operator: String) = new md5sum_builder(i :+ operator)
def build() = println(("md5sum" + i.mkString(" ")).!!)
}
object md5sum_builder {
def apply() = new md5sum_builder
}
md5sum_builder().files("text.txt").files("text1.txt").assignment(">").hashFile("hashes.md5").build()
}
When I try to run the command md5sum text.txt text1.txt > hashes.md5 using this program, it throws the error:
Error: md5sum: stat '>': No such file or directory
I don't know why. Any way to make it work?

Your interface doesn't appear to be well thought out. Notice that files(), hashFile(), and assignment() all do the same thing. So someone could come along and do something like this ...
md5sum_builder().assignment("text0.txt")
.hashFile("text1.txt")
.files(">") // <--shell redirection won't work
.assignment("hashes.md5")
.build()
... and get the same (non-functional) result as your posted example.
Here's a modification that corrects for that as well as allowing redirected output.
case class md5sum_builder private(i :Seq[String], outfile :String = "/dev/null") {
protected def this() = this(Seq.empty[String])
def optionCheck(file :String) = this.copy(i = i ++ Seq("-c", file))
def file(file: String) = this.copy(i = i :+ file)
def hashFile(file: String) = this.copy(outfile = file)
def build() = println(("md5sum" +: i).#|(Seq("tee", outfile)).!!)
}
Now the methods can be in almost any order and still get the expected results.
md5sum_builder().file("text0.txt")
.hashFile("hashes.md5")
.file("text1.txt")
.build()

Related

Spock: mocked class's method is not being matched

I was able to get a passing test for the dumbed down version of my code (thanks to cgrim! Spock: method not recognized as an invocation), but with the real code it won't work unless the getAssetIdBatch returns something that is non-null. I can't figure out why my interactions aren't being implemented. Below, you can see three attempts to get getAssetIdBatch to return the map1 sample.
Here's a dumbed down version of the code:
class VmExportTaskSplitter implements TaskSplitter<Export> {
#Inject
AssetServiceClient assetServiceClient
#Override
int splitAndSend(Export export) {
Map batch = [:]
Map tags = [:]
if (true) {
println('test')
batch = assetServiceClient.getAssetIdBatch(export.containerUuid,
export.userUuid, (String) batch.scrollId, tags)
print('batch: ')
println(batch)
}
return 1
}
}
And now the test:
class VmExportTaskSplitterSpecification extends Specification{
def "tags should be parsed correctly"(){
setup:
Export export = new Export(containerUuid: "000", userUuid: "000", chunkSize: 10)
FilterSet filterSet = new FilterSet()
filterSet.tag = [:]
filterSet.tag['tag.Location'] = 'Boston'
filterSet.tag['tag.Color'] = 'red'
Map<String, String> expectedTags = ['tag.Location':'Boston', 'tag.Color':'red']
ObjectMapper mapper = new ObjectMapper()
export.filters = mapper.writeValueAsString(filterSet)
def assetServiceClient = Mock(AssetServiceClientImpl) {
Map map1 = [assetIds:["1","2","3","4","5"],scrollId:null]
getAssetIdBatch(_ as String,_ as String, null, _ as Map) >> map1
getAssetIdBatch('000', '000', null, ['tag.Location':'Boston', 'tag.Color':'red']) >> map1
getAssetIdBatch(_, _, _, _) >> map1
}
VmExportTaskSplitter splitter = new VmExportTaskSplitter()
splitter.assetServiceClient = assetServiceClient
when:
splitter.splitAndSend(export)
then:
1 * assetServiceClient.getAssetIdBatch(_ as String, _ as String, _, _ as Map)
}
}
When this is run it can be seen that batch is still being printed as null. What am I doing wrong with setting up the interactions?
Using logging directory: './logs'
Using log file prefix: ''
test
batch: null
You –like so many before– ran into the one giant gotcha of Spock: the combination of Mocking and Stubbing and the fact that it has to happen in one line. Form the docs:
Mocking and stubbing of the same method call has to happen in the same interaction.
You stubbed assetServiceClient.getAssetIdBatch to return map1 in your given block and then you verified the mocked call in your then block. The latter one implicitly instructs the mock to return null instead of map1. Think
1 * assetServiceClient.getAssetIdBatch(_ as String, _ as String, _, _ as Map) // >> null
Change that line to
1 * assetServiceClient.getAssetIdBatch(_ as String, _ as String, _, _ as Map) >> map1
and define map1 in the method's scope and it will work as expected.
You probably want to remove the duplicate from the given block as well.
Don't worry about this being in the then block. Spock executes all mocking and stubbing before you enter the when block. Step through the code if you'd like to see it.

load external jar in groovy script in SoapUI

I need to call a method inside Jar from groovy script inside SoapUI project.
Due to the lack of administrative access I can't place that jar in "../bin/ext" folder in SaopUI intall directory.
So the only option left is load the jar in runtime and call the method. Very simple approach.
I tried the below approach.
this.class.classLoader.rootLoader.addURL(new URL("file:///H://Foo-2//Foo.jar"));
def cls = Class.forName("test").newInstance();
cls.add()
This is not working as rootLoader is null.
second approach .
def classLoader = ClassLoader.systemClassLoader
def newClassLoader = new URLClassLoader([new File("file:///H://Foo-2//Foo.jar")
.toString().toURL()] as URL[], classLoader)
def cls = Class.forName("test").newInstance();
this is not working too , it's giving me ClassNotFoundException.
I spent a day in this. even change the class name to lower case after seeing this thread.
Edit 1
I tried this too. and change my code like this.
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
def classpathHacker = new com.eviware.soapui.support.ClasspathHacker ()
log.info "utils=" + groovyUtils
mystring = "file://H://Baz.jar"
com.eviware.soapui.support.ClasspathHacker.addURL( new URL(mystring) )
def cls = new bar() // how to call the static method add of `bar` class ?
log.info cls
My Jar code is too simple. Here it is
public class bar {
public static void main(String[] args) {
add();
}
public static void add(){
String path = "H:" + File.separator + "Groovy" + File.separator + "hi.txt";
File f = new File(path);
f.getParentFile().mkdirs();
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
What all the other option I have? What i am doing wrong?
Solved. Here is the final Groovy script.
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
def classpathHacker = new com.eviware.soapui.support.ClasspathHacker ()
path = groovyUtils.getProjectPath()
myfile = new java.io.File(path + "/Baz.jar")
mystring = "file://" + path + "/Baz.jar"
log.info "myfile=" + myfile
classpathHacker.addFile( myfile )
com.eviware.soapui.support.ClasspathHacker.addFile( myfile )
com.eviware.soapui.support.ClasspathHacker.addURL( new URL(mystring) )
//import Baz
def instance = this.class.classLoader.loadClass( 'bar', true, false )?.newInstance()
instance.add();
Do you know about com.eviware.soapui.support.ClasspathHacker?
Maybe that is away to go about it, if you really cannot put it to the /ext folder.
Reference:
https://community.smartbear.com/t5/SoapUI-Open-Source/Soapui-is-not-loading-external-jar-file-location-added-to/td-p/7619
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
def classpathHacker = new com.eviware.soapui.support.ClasspathHacker ()
log.info "utils=" + groovyUtils
path = groovyUtils.getProjectPath()
myfile = new java.io.File(path + "/ojdbc14.jar")
mystring = "file://" + path + "/ojdbc14.jar"
log.info "myfile=" + myfile
classpathHacker.addFile( myfile )
com.eviware.soapui.support.ClasspathHacker.addFile( myfile )
com.eviware.soapui.support.ClasspathHacker.addURL( new URL(mystring) )
import groovy.sql.*
def sql = groovy.sql.Sql.newInstance( db, userid, password, 'oracle.jdbc.driver.OracleDriver' )

Regex for groovy not working

Please find below my code. I am trying to iterate through files and in a directory and print out all the match to the regex: (&)(.+?\b)
however this doesn't seem to work (it returns an empty string). Where did I go wrong?
import groovy.io.FileType
class FileExample {
static void main(String[] args) {
def list = []
def dir = new File("*path to dir*")
dir.eachFileRecurse (FileType.FILES) { file ->
list << file.name;
def s= "${file.text}";
def w = s.toString();
w.readLines().grep(~/(&)(.+?\b)/)
}
}
}
I figured it out:
import groovy.io.FileType
class FileExample {
static void main(String[] args) {
def list = []
def dir = new File("/path/to/directory/containingfiles")
def p = []
dir.eachFileRecurse (FileType.FILES) {
file -> list << file.name
def s = file.text
def findtp = (s =~ /(&)(.+?\b)/)
findtp.each {
p.push(it[2])
// As I'm only interested in the second matched group
}
}
p.each {
println it
}
}
}
Now, all the matched strings are stored in the array p and can be printed/used elsewhere by p[0] etc.
w.readLines().grep(~/(&)(.+?\b)/) does not do any output, it gives you the matching lines as return value, so if you change it to println w.readLines().grep(~/(&)(.+?\b)/) or w.readLines().grep(~/(&)(.+?\b)/).each { println it }, you will get the matched lines printed on stdout.
Btw.
def s= "${file.text}";
def w = s.toString();
w.readLines()
is just a biiiig waste of time. It is exactly the same as file.text.readLines().
"${file.text}" is a GString that replaces the placeholders on evaluation, but as you have nothing but the file.text placeholder, this is the same as file.text as String or file.text.toString().
But as file.text actually is a String already, it is identical to file.text.
And even if you would need the GString because you have more than the placeholder in it, GString already has a readLines() method, so no need for using .toString() first, even if a GString would be necessary.

antlr4 visitor does not work

I am trying to process .pas file. I generated lexers, parsers, visitors, listeners for grammar
Here is my custom visitor implementation
class GroovyPascalVisitor extends PascalBaseVisitor<ScriptSkeleton> {
private static final String PASCAL_SCRIPT_NAME = "PascalScript"
#Lazy ScriptSkeleton scriptSkeleton = new ScriptSkeleton()
#Override
public ScriptSkeleton visitProgramHeading(
PascalParser.ProgramHeadingContext ctx) {
log.info "Visiting program heading"
def scriptName = ctx.identifier().getText()?.trim()
if (!scriptName) {
scriptName = PASCAL_SCRIPT_NAME +
"${new Random().nextInt(1000)}"
}
scriptSkeleton.scriptName = scriptName
return scriptSkeleton
}
}
Here is the code in my script
def file = new ANTLRFileStream(pas)
def lexer = new PascalLexer(file)
def parser = new PascalParser(new CommonTokenStream(lexer))
tree = parser.program()
stringTree = tree.toStringTree(parser)
visitor = new GroovyPascalVisitor()
skeleton = visitor.visit(tree)
The .pas file content looks like this
program HelloWorld;
begin
writeln('Hello, World!');
end.
But when I run script - it does not println message from log and object scriptSkeleton is null, meaning that it does not invoke visitProgramHeading at all.
What it is the problem?

Groovy cannot call Classloader (NullpointerException)

I have created the following Groovy Script to transform a JSON Document with a Java Library. But somehow I am not able to load the class from a jar that I need. I always get java.lang.ClassNotFoundException: de.is24.gis.geotools.CoordinateTransformer
The Jar file is in the same directory the groovy script is. I can not edit the way I call the groovy script. It is called automatically by a river.
import groovy.json.JsonSlurper
geo = new GeoTransformer()
geo.transform(ctx.document)
class GeoTransformer {
void transform(doc) {
this.getClass().classLoader.addURL(new File("gis-geotools-1.9.0.jar").toURL())
def CoordinateTransformer = Class.forName("de.is24.gis.geotools.CoordinateTransformer").newInstance();
def x = doc.realEstateCommonData.locationDto.geoCoordinateDto.xCoordinate;
def y = doc.realEstateCommonData.locationDto.geoCoordinateDto.yCoordinate;
def coords = CoordinateTransformer.transformFromLambertEuToWgs84(x,z)
println coords.getLatitude()
println coords.getLongitude()
def jsonObj = new JsonSlurper().parseText( '{"type" : "Point", "coordinates" : [' + coords.getLatitude() + ',' + coords.getLongitude() + ']}' )
doc.location = jsonObj
}
}
Not sure why you can't get to the rooLoader, it must be to do with how this Groovy script is executed.
You could try this (obviously untested)
class GeoTransformer {
void transform( doc ) {
def urlLoader = new GroovyClassLoader()
urlLoader.addURL( new File("gis-geotools-1.9.0.jar").toURL() )
def coordTransformer = Class.forName( "de.is24.gis.geotools.CoordinateTransformer",
true,
urlLoader ).newInstance()
def x = doc.realEstateCommonData.locationDto.geoCoordinateDto.xCoordinate;
def y = doc.realEstateCommonData.locationDto.geoCoordinateDto.yCoordinate;
def coords = coordTransformer.transformFromLambertEuToWgs84( x, z )
println coords.latitude
println coords.longitude
doc.location = [ type:'Point',
coordinates:[ coords.latitude, coords.longitude ] ]
}
}
I got rid of the JsonSlurper bit at the bottom, and just created the map directly (I assume doc.location needs to be a map)?
Edit:
This works in the Groovy Console:
def jar = new File( '/path/to/commons-collections-3.2.1.jar' )
def loader = new GroovyClassLoader()
loader.addURL( jar.toURL() )
def bag = Class.forName( 'org.apache.commons.collections.bag.HashBag',
true,
loader ).newInstance()
bag.add( 'tim' )
println bag
println bag.getClass().name
And prints:
[tim]
org.apache.commons.collections.bag.HashBag
I had the same problem when running groovy from java via GroovyShell.
This solution works for me and solves the dependency-loading problems that MeiSign mentions in tim_yates solution. Explanation follows:
def thisLoader = this.class.classLoader
// try the "proper" way to find the root classloader
def rootLoader = DefaultGroovyMethods.getRootLoader(thisLoader)
if (rootLoader == null) {
// Root classloader is not a groovy RootLoader, but we still need it,
// so walk up the hierarchy and get the top one (whose parent is null)
// When running from Java this is sun.misc.Launcher.ExtClassLoader
rootLoader = thisLoader
ClassLoader parentLoader = rootLoader.getParent()
while (parentLoader != null) {
rootLoader = parentLoader
parentLoader = parentLoader.getParent()
}
}
rootLoader.addURL(new File("gis-geotools-1.9.0.jar").toURL())
def CoordinateTransformer =
Class.forName("de.is24.gis.geotools.CoordinateTransformer",
true,
rootLoader).newInstance();
When running groovy from java using groovy.lang.GroovyShell.main, the this.classLoader is GroovyClassLoader.InnerLoader
When running groovy from command line groovy.bat, the class loader is org.codehaus.groovy.tools.RootLoader
When you call getRootLoader, it walks up the classloader hiearchy - with getParent() - until it finds an instance of a RootLoader. If it doesn't it finds null. (That's the NPE in the title of this question)
The problem is that when running from Java the heirarchy tops out at sun.misc.Launcher.ExtClassLoader which is clearly not a groovy class at all, let alone the groovy RootLoader.
Specifically the hiearchy is:
GroovyClassLoader.InnerLoader
--> GroovyClassLoader
---> sun.misc.Launcher.AppClassLoader
----> sun.misc.Launcher.ExtClassLoader
------> null
How it ends up that way is pretty obscure in GroovyMain (but if you really want to set it yourself there's a GroovyShell constructor that takes a ClassLoader).
Anyway, Tim's solution doesn't work in depth, because the new ClassLoader you are creating on the fly is used only to load that class and not subsequent classes. You really do need to add the classpath entries to the root classpath.
So I simply used the real root when the groovy root fails.
Here's the original code from org.codehaus.groovy.runtime.DefaultGroovyMethodsSupport
/**
* Iterates through the classloader parents until it finds a loader with a class
* named "org.codehaus.groovy.tools.RootLoader". If there is no such class
* <code>null</code> will be returned. The name is used for comparison because
* a direct comparison using == may fail as the class may be loaded through
* different classloaders.
*
* #param self a ClassLoader
* #return the rootLoader for the ClassLoader
* #see org.codehaus.groovy.tools.RootLoader
* #since 1.5.0
*/
public static ClassLoader getRootLoader(ClassLoader self) {
while (true) {
if (self == null) return null;
if (isRootLoaderClassOrSubClass(self)) return self;
self = self.getParent();
}
}
private static boolean isRootLoaderClassOrSubClass(ClassLoader self) {
Class current = self.getClass();
while(!current.getName().equals(Object.class.getName())) {
if(current.getName().equals(RootLoader.class.getName())) return true;
current = current.getSuperclass();
}
return false;
}

Resources