Versions Compared


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


  • the code block:

    Code Block
        if (!inventoryItem) {
            logWarning("The InventoryItem with inventoryItemId=${parameters.inventoryItemId} doesn't exist.")
            return failure("Inventory item with id ${parameters.inventoryItemId} was not found.")

    is not really necessary (there is no equivalent in the Minilang version) but I have added it because it seems useful and also to show how you can log a warning message in the console and how you can prematurely return from a service (here we use a "failure" that is still a success, no rollback; but this nice feature is not used much in OFBiz)

  • the code is really expressive and easy to read; no technical stuff that is not part of the business logic is needed (similar to Minilang); the code is also very concise (50% of the Minilang equivalent)
  • error handling: as in Minilang error handling related code is not necessary in the 90% of the cases; when a service call or an entity operation fail the service execution is stopped and the engine takes care of returning the "error" and rolling back the transactions; if you want to avoid this behavior for a special handling (equivalent of the Minilang's break-on-error="false" attribute) you can simply wrap the call in a try/catch block; for example:

    Code Block
    try {
        result = runService('updateProduct', [productId: 'CodeThatDoesntExist'])
    } catch(Exception e) {
        return error('something wrong happened: ${e.getMessage()}')

    However in most of the cases you shouldn't worry about errors returned by services and entity operations because the framework will take care of returning the proper error map for you (as it happens in Minilang)

  • dispatcher and delegator objects are available with all their rich api (just use them as they are already in the context) but not necessary for the most common cases (calling sync services, fetching and manipulating simple data etc...) because for them you can use the DSL language: all the calls like runService, findOne, findList, makeValue etc... fetch the dispatcher/delegator from the context behind the lines
  • runService accepts and an input map and there is no need to add to it the userLogin object because the method will automatically fetch it from the context if not already in the map (same as in Minilang)
  • the methods error(), failure(), success() (you can optionally pass a string to them for the message) all return a valid service output map; success/failure represent a "success" (no rollback) while error will cause a rollback; however in most of the cases you will not need to call "error" because if something goes wrong the framework will do it for you (similar to Minilang)
  • with IDEs that support Groovy (I am using Idea) you will be able to debug groovy services like in Java; assisted completion features are also pretty good for Groovy