groovy configslurper Environment No such property when compiled to jar - groovy

I'm having a trouble reading an environment configuration stored in a .groovy script from a jar created as a compiled version of my main script. The script version runs fine. The "sandbox3" reference in the error message refers to an environment defined in the config file. This it the error message I get:
server_control_web_services>runobiadmin2 -e sandbox3
Caught: groovy.lang.MissingPropertyException: No such property: sandbox3 for class: script_from_command_line
groovy.lang.MissingPropertyException: No such property: sandbox3 for class: script_from_command_line
at script_from_command_line.run(script_from_command_line:1)
Groovy 2.4.5
When running the original script the code below behaves as expected setting config to the environment passed from the command line. obieeadmincfg.groovy is located in the same directory as the jar file.
URL url = OBIEEAdmin.class.getClassLoader().getResource('obieeadmincfg.groovy')
config = new ConfigSlurper(opt.e).parse(url)

Related

How add dependencies into groovy script?

I try to add HttpBuilder into groovy script, but can do it only manually (Alt+Ctrl+Shift+S add dependencie). But when I start script I have error in line of creating new httpbuilder instance java.lang.ClassNotFoundException: org.apache.http.client.HttpClient. I manualy add HttpClient, butClassNotFoundException: net.sf.json.JSONObject and so on. But when I add Ini library it works fine.
I also tried to use #Grab
main()
def main() {
#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')
And have compilation error
Error:Groovyc: While compiling GroovyTests: java.lang.RuntimeException: Error grabbing Grapes -- [download failed: net.sf.json-lib#json-lib;2.3!json-lib.jar]
And net in def http = new groovyx.net.http.HTTPBuilder('http://www.codehaus.org') is red and Cannot resolve a symbol 'net' error
will be glad to any help
Since you have now installed the groovy executables as per the comments, the following code:
#Grab('org.codehaus.groovy.modules.http-builder:http-builder:0.7')
import groovyx.net.http.HTTPBuilder
def http = new HTTPBuilder('https://jsonplaceholder.typicode.com')
def res = http.get(path: '/users')
println "Number of users: ${res.size()}"
should now run and print:
─➤ groovy solution.groovy
Number of users: 10
─➤
(tested on Groovy Version: 2.5.8 JVM: 1.8.0_232 Vendor: AdoptOpenJDK OS: Linux)
One thing that might be disrupting the artifact resolution is if you have a custom grapeConfig.xml file. This file (if it exists) should be under <user home dir>/.groovy/grapeConfig.xml and the default text that groovy uses if no grapeConfig.xml file is present can be found here:
https://github.com/apache/groovy/blob/master/src/resources/groovy/grape/defaultGrapeConfig.xml
In addition, if you need to debug grapes downloads, you should try the following flags (again as mentioned in the comments):
─➤ groovy -Dgroovy.grape.report.downloads=true -Divy.message.logger.level=4 yourGroovyScript.groovy
which should print information on what grapes are actually doing when the resolution fails.
What does your groovy -v look like? i.e. what version of groovy and what jdk are you on?

"Unrecognized option: --format=COBERTURAXML" in trying to convert JSCover report to cobertura xml

I'm trying to convert JSCover to cobertura xml.
Based on what i've read the command is as follows:
java -cp JSCover-all.jar jscover.report.Main --format=COBERTURAXML REPORT-DIR SRC-DIRECTORY
But I get an error
"Error: Could not find or load main class jscover.report.Main"
Even if I set the fully qualified path of there the JSCover-all.jar is located.
So I tried including the JSCover-al.jar into the classpath and run the following command instead:
java -cp jscover.report.Main --format=COBERTURAXML target/local-storage-proxy target/local-storage-proxy/original-src
I no longer get the first error but i'm now getting the following error:
Unrecognized option: --format=COBERTURAXML
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
I hope someone could help me with it. Many thanks!
The first attempt is the correct approach. The error means that JSCover-all.jar is not in the same directory that you are executing the command from. An absolute path to is not needed - a relative one will do.
In the second approach, you have passed 'jscover.report.Main' as the class-path to the JVM and '--format=COBERTURAXML' as parameter to the 'java' command.

Groovy - How to Build a Jar

I've written a Groovy script which has a dependency on a SQL Server driver (sqljdbc4.jar). I can use the GroovyWrapper (link below) to compile it into a JAR, however how can I get dependencies into the Jar? I'm looking for a "best practice" sort of thing.
https://github.com/sdanzan/groovy-wrapper
Both of the replies below have been helpful, but how can I do this for signed Jar files? For instance:
Exception in thread "main" java.lang.SecurityException: Invalid signature file d
igest for Manifest main attributes
In the groovy wrapper script, you'll see this line near the bottom:
// add more jars here
That's where you can add your dependencies. If the jar file is in the same directory you're building from, add a line like this:
zipgroupfileset( dir: '.', includes: 'sqljdbc4.jar' )
Then rerun the script and your jar will include the classes from sqljdbc4.jar.
Edit:
If the jar file you depend on is signed and you need to maintain the signature, you'll have to keep the external jar. You can't include jar files inside of other jar files without using a custom classloader. You can, however, specify the dependency in the manifest to avoid having to set the classpath, i.e. your jar still executable with java -jar myjar.jar. Update the manifest section in the wrapping script to:
manifest {
attribute( name: 'Main-Class', value: mainClass )
attribute( name: 'Class-Path', value: 'sqljdbc4.jar' )
}
From your link, if you look at the source of the GroovyWrapper script, there's this line:
zipgroupfileset( dir: GROOVY_HOME, includes: 'embeddable/groovy-all-*.jar' )
zipgroupfileset( dir: GROOVY_HOME, includes: 'lib/commons*.jar' )
// add more jars here
I'd explicitly add it there.

Error loading Groovy config file from JAR

I have an application that is running on compiled Groovy code in a jar.
The groovy code is all being loaded/executed correctly, however, I have a step that attempts to load a groovy-config file from the root of the JAR, but it is failing.
The code below is from a groovy class that is being run from the JAR, and here it attempts to load the groovy config file config.props from the root of the jar:
URL url = this.getClass().getClassLoader().getResource("config.props")
logger.info( url.toString() )
if(!url)throw new IllegalArgumentException("'$resource' not found ")
GroovyScriptEngine gse = new GroovyScriptEngine( url )
...
gse.run(url.file, binding)
When I run the above I get the following error:
Message: Cannot open URL: jar:file:/usr/local/libs/test-all.jar!/config.props
Does anyone have any idea how to load a file from a root of a jar? I have temporarily set the permissions to 777 and have checked that the file exists/spelling correct.
Ok - I think I have resolved this.
It looks like the error was in
gse.run(url.file, binding)
the url.file passed the full absolute path including file: protocol to the gse - I changed this to just "config.props" and it seemed to have got past this (there is another error now, but seems to be further on).

How do you get the path of the running script in groovy?

I'm writing a groovy script that I want to be controlled via a properties file stored in the same folder. However, I want to be able to call this script from anywhere. When I run the script it always looks for the properties file based on where it is run from, not where the script is.
How can I access the path of the script file from within the script?
You are correct that new File(".").getCanonicalPath() does not work. That returns the working directory.
To get the script directory
scriptDir = new File(getClass().protectionDomain.codeSource.location.path).parent
To get the script file path
scriptFile = getClass().protectionDomain.codeSource.location.path
As of Groovy 2.3.0 the #SourceURI annotation can be used to populate a variable with the URI of the script's location. This URI can then be used to get the path to the script:
import groovy.transform.SourceURI
import java.nio.file.Path
import java.nio.file.Paths
#SourceURI
URI sourceUri
Path scriptLocation = Paths.get(sourceUri)
Note that this will only work if the URI is a file: URI (or another URI scheme type with an installed FileSystemProvider), otherwise a FileSystemNotFoundException will be thrown by the Paths.get(URI) call. In particular, certain Groovy runtimes such as groovyshell and nextflow return a data: URI, which will not typically match an installed FileSystemProvider.
This makes sense if you are running the Groovy code as a script, otherwise the whole idea gets a little confusing, IMO. The workaround is here: https://issues.apache.org/jira/browse/GROOVY-1642
Basically this involves changing startGroovy.sh to pass in the location of the Groovy script as an environment variable.
As long as this information is not provided directly by Groovy, it's possible to modify the groovy.(sh|bat) starter script to make this property available as system property:
For unix boxes just change $GROOVY_HOME/bin/groovy (the sh script) to do
export JAVA_OPTS="$JAVA_OPTS -Dscript.name=$0"
before calling startGroovy
For Windows:
In startGroovy.bat add the following 2 lines right after the line with
the :init label (just before the parameter slurping starts):
#rem get name of script to launch with full path
set GROOVY_SCRIPT_NAME=%~f1
A bit further down in the batch file after the line that says "set
JAVA_OPTS=%JAVA_OPTS% -Dgroovy.starter.conf="%STARTER_CONF%" add the
line
set JAVA_OPTS=%JAVA_OPTS% -Dscript.name="%GROOVY_SCRIPT_NAME%"
For gradle user
I have same issue when I'm starting to work with gradle. I want to compile my thrift by remote thrift compiler (custom by my company).
Below is how I solved my issue:
task compileThrift {
doLast {
def projectLocation = projectDir.getAbsolutePath(); // HERE is what you've been looking for.
ssh.run {
session(remotes.compilerServer) {
// Delete existing thrift file.
cleanGeneratedFiles()
new File("$projectLocation/thrift/").eachFile() { f ->
def fileName=f.getName()
if(f.absolutePath.endsWith(".thrift")){
put from: f, into: "$compilerLocation/$fileName"
}
}
execute "mkdir -p $compilerLocation/gen-java"
def compileResult = execute "bash $compilerLocation/genjar $serviceName", logging: 'stdout', pty: true
assert compileResult.contains('SUCCESSFUL')
get from: "$compilerLocation/$serviceName" + '.jar', into: "$projectLocation/libs/"
}
}
}
}
One more solution. It works perfect even you run the script using GrovyConsole
File getScriptFile(){
new File(this.class.classLoader.getResourceLoader().loadGroovySource(this.class.name).toURI())
}
println getScriptFile()
workaround: for us it was running in an ANT environment and storing some location parent (knowing the subpath) in the Java environment properties (System.setProperty( "dirAncestor", "/foo" )) we could access the dir ancestor via Groovy's properties.get('dirAncestor').
maybe this will help for some scenarios mentioned here.

Resources