Is there any way to use groovy and java code for the same class? - groovy

I mainly program in groovy, but occasionally it's too slow. So I write a separate .java class, and put the code that needs to run faster in a java method and call that java method from my groovy code.
This causes me to end up with two separate files and two separate classes. Is there any way I could embed a java method right into the groovy file, maybe marking it with an annotation to indicate that it is java?

This is the idea behind groovy++. Marking a class or method with the #Typed annotation will cause it to use static typing instead of dynamic typing, while still retaining a lot of goodness of groovy.
While not exactly java, typed groovy++ methods generally perform about the same as java would.
More information on groovy++ is available at: https://code.google.com/p/groovypptest/wiki/Welcome

You don't need to do anything special.
Just write the Java class behind the groovy class. 99% of all Java source is valid groovy source as well.
class GroovyClass {
def a;
def doSomething(x,y) { return x*y; }
}
class JavaClass {
SomeType someVar;
public JavaClass() { /* ... */ } // some contructor
public void doit(String a, int b) {} // full typed method, that is java
}
Groovy++ is somethign completely different.
The JavaClass needs to have everything fully typed to be "Java" however your problem can be solved far easyer if you just use types in the relevant groovy methods.
class AnotherGroovyClass {
// typed
public Result someMethod(SomeArg arg1, SomeOtherArg arg2) {
}
def someVariable; // untyped
}
If you think the lack of speed comes from the dynamic nature of groovy then just use full types at the relevant points.

Related

How to declare a constructor or extends a class of a groovy script?

I am working on a shared library for Jenkins, and I want to access some utilities methods between some classes, but not all of them, thus I have established some statements:
I would like to avoid using static methods, since it does not access pipeline steps directly, and passing the pipeline instance every call would be a pain;
I would like to avoid a singleton as well, or prefixing every method call with the util class' instance;
Since it is not supposed to be shared between all classes I would like to avoid putting every method as a file on vars/ special directory, but I would like a similar behavior;
Despite extending the class would be a anti-pattern, it would be acceptable, though I would like to avoid the verbose Java syntax for declaring the class the same name as the file, once it is implicit in groovy;
This question does solve my problem partially, although there are issues with serialization, I noted that when I use checkpoint and some build is resumed from some stage, the instance loses all extra methods.
This other question would have helped me fix the serialization issue, however the author seems the have solved the root cause of his problem using a way that is not the original question titled for.
Is there a way to extends a implicit script class in groovy without using the class NameOfFile extends SomeOtherClass { put every thing inside this block } syntax? And without working with inner-class?
Or else, is there a way to declare a constructor using the script groovy syntax analogue as the previous question?
Or even, is there a way to change the serialization behavior to install the extra methods again after unserializing?
Appendix
The script syntax works more-or-less like this:
Consider the content of file src/cicd/pipeline/SomePipeline.groovy:
package cicd.pipeline
// there is no need to wrap everything inside class SomePipeline,
// since it is implicit
def method() {
// instance method, here I can access pipeline steps freely
}
def static otherMethod() {
// static method, here it is unable to access pipeline steps
// without a instance
}
#groovy.transform.Field
def field
def call() {
// if the class is used as method it will run
this.method()
SomePipeline.otherMethod() // or simply otherMethod() should work
this.field = 'foo'
println "this instance ${this.getClass().canonicalName} should be cicd.pipeline.SomePipeline"
}
// any code other than methods or variables with #Field
// annotation will be inside a implicit run method that is
// triggered likewise main method but isn't a static one
def localVar = 'foo'
println "It will not execute on constructor since it is on run: $localVar"
println "Method: ${org.codehaus.groovy.runtime.StackTraceUtils.sanitize(new Throwable()).stackTrace[0].methodName}"
println "this instance ${this.getClass().canonicalName} should be cicd.pipeline.SomePipeline"
If I was going to use the Java verbose syntax I would have to wrap almost everything inside a class SomePipeline which is implicit in groovy, this is the script syntax I want to keep.
I realised that this.getClass().superclass.canonicalName when outside Jenkins pipeline is groovy.lang.Script and when inside pipeline is org.jenkinsci.plugins.workflow.cps.CpsScript and based on this resource I was able to elaborate the following solution:
abstract class CustomScript extends org.jenkinsci.plugins.workflow.cps.CpsScript {
public CustomScript() {
// do something here, it will always execute regardless
// serialization, and before everything
}
}
#groovy.transform.BaseScript CustomScript baseScript
That is it, worked as expected! Of course you can elaborate this solution better in order to reduce repeating and avoid inner-classes, but I will leave it for your imagination.

Groovy star import and usage of "partial" packages

To my surprise I have learned today that the following works just fine in Groovy:
import java.util.concurrent.*
def atomicBool = new atomic.AtomicBoolean(true)
i.e. after the star import, I can use a 'partial' package to refer to java.util.concurrent.atomic.AtomicBoolean.
Obviously, the same is not valid in Java:
import java.util.concurrent.*;
public class Sample {
public static void main(String[] args) {
// compiler error: 'atomic' cannot be resolved to a type
new atomic.AtomicBoolean(true);
}
}
So it seems that Groovy's idea of a package is similar to C++ (or C#) namespaces in this regard.
Question to the Groovy experts:
Is this by design or is it a (potentially unintended) side effect of the way the interpreter treats star imports?
If it is by design, can you point me to a section in the documentation or language specification where this behavior is documented? (There is no mention of this in the documentation on Star Import and neither in the language spec as far as I can tell or at least I couldn't find anything.)
Based on Groovy source code, this behavior seems to be intended. Before we dig deeper into Groovy internals you have to be aware of one thing - Groovy compiles to a bytecode that can be represented by a valid Java code. It means that Groovy code like the one form your example actually compiles to something like this (without compile static and type checked transformations):
import groovy.lang.Binding;
import groovy.lang.Script;
import java.util.concurrent.atomic.AtomicBoolean;
import org.codehaus.groovy.runtime.InvokerHelper;
import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;
import org.codehaus.groovy.runtime.callsite.CallSite;
public class test extends Script {
public test() {
CallSite[] var1 = $getCallSiteArray();
}
public test(Binding context) {
CallSite[] var2 = $getCallSiteArray();
super(context);
}
public static void main(String... args) {
CallSite[] var1 = $getCallSiteArray();
var1[0].call(InvokerHelper.class, test.class, args);
}
public Object run() {
CallSite[] var1 = $getCallSiteArray();
AtomicBoolean atomicBool = (AtomicBoolean)ScriptBytecodeAdapter.castToType(var1[1].callConstructor(AtomicBoolean.class, true), AtomicBoolean.class);
return var1[2].callCurrent(this, atomicBool);
}
}
As you can see this Java class uses full java.util.concurrent.atomic.AtomicBoolean import and this is actually what Groovy transforms your input source code to.
How does it happen?
As you may know Groovy builds Abstract Syntax Tree (AST) from the input source file and it iterates over all nodes (like expressions, variable definitions, method calls etc.) and applies transformations. Groovy uses class called ResolverVisitor that is designed to resolve types. When Groovy compiles your code it finds ConstructorCallExpression:
new atomic.AtomicBoolean(true)
It sees that the expected type of the object you are trying to create is atomic.AtomicBoolean, so ResolverVisitor starts resolving the type by calling resolveOrFail(type, cce); at line 1131.
It tries several resolving strategies that fail until it reaches method resolveFromModule at line 695. What happens here is it iterates over all star imports (single java.util.concurrent.* in your case), then it concatenates star import with the type name and it checks if qualified name created from this concatenation is a valid type class. Luckily it is in your case:
When type gets resolved, Groovy replaces initial type with this resolved valid type name in the abstract syntax tree. After this operation your input code looks more like this:
import java.util.concurrent.*
java.util.concurrent.atomic.AtomicBoolean atomicBool = new java.util.concurrent.atomic.AtomicBoolean(true)
This is what compiler gets eventually. Of course fully qualified name gets replaced with the import (this is what Java compiler does with qualified names).
Was this "feature" introduced by designed?
I can't tell you that. However we can read from the source code, that this happens on purpose and type resolving like this is implemented with intention.
Why it is not documented?
I guess no one actually recommend using imports that way. Groovy is very powerful and you are able to do many things in a many different ways, but it doesn't mean you should do so. Star imports are pretty controversial, because using star imports over explicit imports makes your code more error-prone due to possible class import conflicts. But if you want to know exact answer to this kind of questions you would have to ask Groovy language designers and core developers - they may give you straight answer without any doubts.

checker framework: Supress Warnings in default constructor

I have two constructors: normal ctor which initialises the object properly and a second default ctor for Hibernate which generates initialize fields warnings. What's the preferred way to get rid of the warnings?
package test;
public class Example {
String x;
public Example(String x) {
this.x = x;
}
Example() {
// Ctor for Hibernate, warnings generated here.
}
}
You didn't mention looking in the documentation, so I'm not sure whether you have done so. The Checker Framework manual contains a chapter titled "Suppressing warnings", which might contain all the information you need.
The most common approach is to write a #SuppressingWarnings annotation, which is the standard way to suppress warnings from the Java compiler.
You should write it on the smallest program element possible (such as a local variable declaration rather than the whole constructor or class), and you should supply the most specific key possible. The reason is to avoid accidentally suppressing more warnings than you intended.

Groovy abstract classes constructors and inheritance

I have an abstract java class which has a constructor and I'm extending it from a groovy class. (the idea is to keep the java class as a contract inside the app and load external groovy classes that implement certain constructors and methods)
How can I force in Groovy to implement an abstract super class's constructor?
Does Groovy allow to force the implementation of the abstract parent class's constructor?
The thing is that the Eclipse Groovy IDE is not forcing me to implement the constructor of the parent class in the subclass, I thougth Groovy would create it automatically and so that was the reason to not forcing it. However at run time when trying to get the constructor using java reflection fails it fails if I don't define the parent constructor in the subclass.
(I have 0 experience in Groovy)
It looks like an unchecked situation in the compiler. Upon decompiling, the extending class gets an empty constructor. Tests should get you covered, since this situation doesn't work in runtime.
I don't know of a way to use this class; i tried the ways i know:
abstract class AbstractClass {
String string
Integer integer
AbstractClass(String string, Integer integer) {
this.string = string
this.integer = integer
}
}
class ImplClass extends AbstractClass { }
// every constructor fails
abs1 = new ImplClass('a', 1)
abs2 = [string: 'b', integer: 2] as ImplClass
abs3 = new ImplClass(abs: 'c', a: 3)
abs4 = ImplClass [string:'d', integer:4]
Neither of them worked in runtime, but compiled fine ;-). The situation is more about compile error vs runtime error. Maybe filling a JIRA?
On the other way around, if you needed to inherit the constructors, you could go for #groovy.transfom.InheritConstructors in the extending class. This way you would have the constructors without needing to call super() explicitly.

How Does "Use" work in groovy?

Hi I have the following Code Snippet;
class StringCalci
{
static def plus(Integer self, Integer Operand)
{
return self.toInteger() * Operand.toInteger()
}
}
use (StringCalci)
{
println("inside the Use method!")
println( 12 + 3 )
}
println(12+3)
I was been shocked to see the use of Use in groovy. The thing is this I can add methods to the Class at run-time(my own methods).when I was looking at the above code, I was Thinking how does Groovy make things possible like this! The use of println inside the Use is multiplying the two given numbers(because I have Override the plus method) , where as the outside println adds it! My question is how does Groovy recognise the println executes in Use and println outside the Use. Is Use is a keyword/method? I need to understand behind the scenes of this process.. Please let me know :)
Thanks in Advance :)
Welcome to the wonderful world of dynamic languages where everything is possible and nothing is certain!
This feature is called Categories. As for the implementation:
use is in fact not a keyword but a method which the Groovy runtime adds to the Object class, which makes it available everywhere.
I think the functionality is implemented mainly in the class GroovyCategorySupport
Judging from the Javadoc, it's based on keeping a map of overriden methods in a ThreadLocal which is then consulted for every method call.
yeah, that's not so great for performance, but so are pretty much all the dynamic "magic" features that Groovy and similar languages offer (and there's lots of them).

Resources