Groovy importing static nested classes - groovy

The following two classes in the same package:
Imported.groovy
class Imported {
static class Inner {
}
}
Main.groovy
import Imported
class Main {
static main(args) {
new Imported.Inner()
}
}
When run:
$ groovy Main.groovy
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
/tmp/Main.groovy: 5: unable to resolve class Imported.Inner
# line 5, column 5.
new Imported.Inner()
^
1 error
Any reason this is happening? How to properly import static nested classes?

Just compile Imported.groovy: groovyc Imported.groovy so that you have Imported.class and Imported$Inner.class.
Then simply invoke groovy Main.groovy and it should work.
If you want to have some "import/include" functionality, check Including a groovy script in another groovy and how to simply import a groovy file in another groovy script.

Related

How to declare a Groovy class in one file and use it in a Groovy script in another file?

After reading many threads I am stuck on this very simple task.
I have a sandbox project with only two files :
src/main/groovy/classes/foo
package classes.foo
class Foo{
#Override
String toString() {
return "Foo"
}
}
and src/main/groovy/scripts/script.groovy
package scripts
import classes.Foo
def foo = new Foo()
print foo.toString()
Now if I run the command :
groovy src/main/groovy/scripts/script.groovy
I get the following error :
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
src\main\groovy\scripts\utils\script.groovy: 3: unable to resolve class classes.Foo
# line 3, column 1.
import classes.Foo
^
1 error
How can I use my class Foo in my script script.groovy ?
As suggested by dagget, I had to specify the classpath based on my root folder which in my case is groovy :
groovy -cp src/main/groovy src/main/groovy/scripts/script.groovy

Getting unknown type : import in groovy in Jenkins Pipeline

I am trying to create a Jenkins Pipeline Script using groovy. However, the import statement is giving me a compilation error - Unknown Type : Import. Not sure why.
You should define import jxl.* at the top of the pipeline script, e.g.
import jxl.*
node {
stage('Execute Tests') {
try {
dir('.') {
sh '......' // etc.
}
}
}
}
When you added it inside node {} block Jenkins was looking for a method instead of import class statement. The good convention is to put all import statements at the top of the Groovy file.

opennlp.groovy has NullPointerException

I am trying to get the following code snippet from GitHub to work so that I can use OpenNLP tools in Groovy scripts.
(OpenNLP class from https://gist.github.com/nagaimasato/1178725)
#!/usr/bin/env groovy
#Grapes(
#Grab(
group='org.apache.opennlp',
module='opennlp-tools',
version='1.5.3'
)
)
import opennlp.tools.tokenize.*
import opennlp.tools.postag.*
OpenNLP nlp = new OpenNLP()
def tokens = nlp.workTokenize("Hello world")
println tokens
class OpenNLP {
static TokenizerModel tokenizerModel
static POSModel posModel
static {
def classLoader = OpenNLP.class.classLoader
classLoader.getResource('opennlp/en-token.bin').withInputStream {
tokenizerModel = new TokenizerModel(it)
}
classLoader.getResource('opennlp/en-pos-maxent.bin').withInputStream {
posModel = new POSModel(it)
}
}
Tokenizer tokenizer
POSTagger tagger
OpenNLP() {
tokenizer = new TokenizerME(tokenizerModel)
tagger = new POSTaggerME(posModel)
}
List workTokenize(String text) {
return tokenizer.tokenize(text)
}
List posTag(List tokens) {
return [tokens, tagger.tag(tokens)].transpose()
}
}
I get the following error when I try to run the script:
Caught: java.lang.ExceptionInInitializerError
java.lang.ExceptionInInitializerError
at Greetings.class$(Greetings.groovy)
at Greetings.$get$$class$OpenNLP(Greetings.groovy)
at Greetings.run(Greetings.groovy:13)
Caused by: java.lang.NullPointerException: Cannot invoke method withInputStream() on null object
at OpenNLP.<clinit>(Greetings.groovy:25)
... 3 more
I have en-token.bin and en-pos-maxent.bin in the right place for the script to find, but classLoader.getResource("opennlp/en-token.bin") is indeed null when I print it. Any ideas?
Make sure the en-token.bin and en-pos-maxent.bin files are in a directory named opennlp and that the classpath includes the parent directory of opennlp.
Note that ./ is included in the classpath when you execute your Groovy script, so if you have your opennlp directory in the same directory as your Groovy script and you also invoke the Groovy script while you are in that directory, it should work (at least it worked for me). But if you execute the script while you are not currently in that directory (e.g. by using a path like path/to/script.groovy) it won't work. In that case, you can just invoke it using groovy -cp path/to path/to/script.groovy, thus putting the parent directory of your opennlp directory into the classpath manually.

lookupScriptFiles "true" in the loadClass() method

Extended GroovyClassloader and override loadclass method
If I make lookupScriptFiles "true" in the loadClass() method the script run and doesn't require an import statement referencing a groovy class in a different package
i have extended GroovyClassloader, and override the loadclass method, in the loadclass the argument lookupScriptFiles =true
When this is true, it sucessfully compiles even first.groovy don't have import statement
when lookupScriptFiles=false it throws compilation error as expected.
my source code snippet
C:\>cat first.groovy
def cos=new Second()
==============================================================
C:>cat Second.groovy
package com.test
class Second
{
Second()
{
println "Anish"
}
}
=========================================================
C:\bin>echo %CLASSPATH%
C:\zGroovy\bin;C:\vsexclude\opt\groovy-1.7.2\embeddable\groovy-all-1.7.2.jar
===============================================
C:\vsexclude\trees\bac-4.2\workspace\zGroovy\bin>java GCtest
path------>>C:\first.groovy
Anish
=================================
import groovy.lang.GroovyClassLoader;
import org.codehaus.groovy.control.CompilationFailedException;
import org.codehaus.groovy.control.CompilerConfiguration;
/**
* #author Anish
*/
public class GCloader extends GroovyClassLoader {
public GCloader(ClassLoader parent) {
super(parent, new CompilerConfiguration());
}
#Override
public Class<?> loadClass(final String name, boolean lookupScriptFiles,
boolean preferClassOverScript, boolean resolve)
throws ClassNotFoundException, CompilationFailedException {
//return loadFiles(name, true, preferClassOverScript, resolve);
return super.loadClass(name, true,
preferClassOverScript, resolve);
}
}
Assuming your question is:
If I set lookupScriptFiles to true, can I remove the import statements from my groovy scripts?
Then the answer is no. The classloader will try to lookup scripts it doesn't know about, but you will still need to imports to tell it in which packages to look for each class
Update
So, you have two groovy files in the same directory, one of which you have arbitrarily added a package statement to.
I assume you are loading the classes straight from scripts (yet another thing you don't say in your question)
If this is the case, then you will need to tell the classloader to lookup the other scripts to compile to classes.
If you don't -- as you have seen -- it will not work (imports or no imports)
However, putting two groovy files in the same folder, and just adding a package line to one of them is awful coding practice, and I'm surprised you got anything working

How to import org.codehaus.groovy.scriptom.* on Groovy?

I'm trying to run a Groovy app to manipulate Excel files on STS (by SpringSource) 2.3.0.
My Groovy version is 1.7.
Class:
package com.mytool
import org.codehaus.groovy.scriptom.ActiveXObject
/**
* #author Mulone
*
*/
class SurveyTool {
static main(args) {
print 'test'
def wshell = new ActiveXObject('Wscript.Shell')
wshell.popup("Scriptom is Groovy")
}
}
Sadly, this is what I get:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
C:\workspace\SurveyTool\src\com\geoadapta\surveytool\SurveyTool.groovy: 6: unable to resolve class org.codehaus.groovy.scriptom.ActiveXObject
# line 6, column 1.
import org.codehaus.groovy.scriptom.ActiveXObject
^
1 error
I also tried to rename ActiveXObject to ActiveXProxy with the same result.
I tried to import scriptom manually from the package scriptom-all-assembly-1.6.0 but I didn't work.
Any idea?
Cheers
Ops, I fixed it by importing all the jar files manually and by putting jacob-1.14.3-x86.dll in the project folder.

Resources