Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Groovy Libraries allow custom Groovy functions and helpers to be shared and reused across all Groovy scripts in FlexDeploy

Table of Contents
maxLevel6
minLevel1
include
outlinefalse
indent
exclude^Groovy Libraries allow
stylenone
typelist
printabletrue
class

...

The authored script code for each library is wrapped in a class declaration like so

Code Block
languagegroovy
package com.flexagon.groovy.custom;
// imports in the script are moved here

public class LIB_MY_LIB {
  // your script code is inserted here  
}

This class is compiled once at server startup and then on each change of the library script it is recompiled.

Finally, when running a Groovy script, an instance of this library class is instantiated and made available to the script as a variable matching the Library Key.

You can think of it as FlexDeploy automatically adding the following lines at the beginning of all of your Groovy scripts:

Code Block
languagegroovy
def LIB_MY_LIB = new com.flexagon.groovy.custom.LIB_MY_LIB(); 

Importing Other Custom Libraries

Info

Importing other custom libraries is only supported in version 9.0.0.2+

Custom libraries are not made available in other custom libraries by default, however they can be imported as needed. The below code snippet shows how the custom LIB_PIPELINE_UTILS imports and uses another custom library LIB_LOGGER.

Code Block
languagegroovy
// imports omitted for brevity

// create a new instance of our custom library
// the LOG variable should be passed in the constructor for any imported custom library instance
def logger = new com.flexagon.groovy.custom.LIB_LOGGER(LOG)

void myPipelineFunction()
{
  logger.logMessage("Logger library import")
  // code omitted for brevity
}

Static Methods

Methods can be called statically, without an instance created, if they have the static modifier. Note - this only applies when importing other custom libraries since other Groovy scripts have instances created behind the scenes. See Library Compilation above.

For example:

LIB_LOGGER

Code Block
languagegroovy
static void logMessage(String message)
{
  // log
}

void logMessage2(String message)
{
  // log
}

LIB_PIPELINE_UTILS

Code Block
languagegroovy
import com.flexagon.groovy.custom.LIB_LOGGER;

def loggerInstance = new LIB_LOGGER(LOG);

void myPipelineFunction()
{
  // This WILL work
  LIB_LOGGER.logMessage("Logger library static method")
  
  // This will NOT work
  LIB_LOGGER.logMessage2("Logger library instance method")
  
  // BOTH of these will work
  loggerInstance.logMessage("Logger library static method")
  loggerInstance.logMessage2("Logger library instance method")
}
Note

Static method caveat

A final note on static methods - Static methods cannot access instance variables. This means if you have a static method defined in your library and try to access FLEXDEPLOY, LOGor any other instance variables it will not work and produce an error like the following: You attempted to reference a variable in the binding or an instance variable from a static context.

In this case you must either remove the static modifier or not use the variable in question.

Circular Imports

Warning

Circular imports of custom libraries are not allowed and if found an error will be thrown [Circular imports detected. Please check if libraries are creating instances of each other outside of a function scope..] when attempting to test or save the library.

The below example demonstrates a circular library import and why its a problem:

  • LIB_ONE

Code Block
def libTwo = new com.flexagon.groovy.custom.LIB_TWO(LOG)

def myFunction() {
  // do some logic
}
  • LIB_TWO

Code Block
def libOne = new com.flexagon.groovy.custom.LIB_ONE(LOG)

def myFunction() {
  // do some logic
}

Lets look at what happens when FlexDeploy compiles and creates instances of your custom libraries for other Groovy scripts to use.

  1. FlexDeploy will iterate through all your Groovy Libraries and create an instance of each.

  2. A new instance of LIB_ONE is created.

  3. During initialization of LIB_ONE it will create a new instance of LIB_TWO as declared on line 1 of LIB_ONE

  4. An instance of LIB_TWO is created during step 3. This in turn creates an instance of LIB_ONE as declared on line 1 of LIB_TWO.

    1. We are now stuck in a loop between steps 3 and 4, infinitely creating new instances. This is what is known as a circular dependency and will result in an error being thrown.

Tip

If it is absolutely necessary to have a circular dependency between libraries, then the creation of library instances should be done within a function scope.

  • LIB_ONE

Code Block
def libTwo = new com.flexagon.groovy.custom.LIB_TWO(LOG)

def myFunction() {
  // do some logic
}
  • LIB_TWO

Code Block
import com.flexagon.groovy.custom.LIB_ONE;

def myFunction() {
  def libOne = new LIB_ONE(LOG)
  // do some logic
}