Pimp My Groovy – boosting CPI Groovy developments with IntelliJ IDEA
[Update 15 Mar 2022]
This post was written a while back. Technology moves at the light of speed, and as such, some of what is described here is out of date, but I don’t have the time to adjust it continuously to be always in sync with the latest. If you are interested in developing and testing your Groovy scripts, I’d suggest you check my E-Bite on this topic instead which is more current and should provide you a more comprehensive approach to get started. https://blogs.sap.com/2020/06/15/learn-to-develop-groovy-scripts-for-sap-cpi-with-our-new-sap-press-e-bite/
Some months back, I mentioned on LinkedIn about switching from Eclipse to IntelliJ IDEA as my IDE for Java and Groovy developments.
After months of using it on my current project with CPI as the integration platform, I am very pleased with the productivity and efficiency boosts it has given me when developing Groovy scripts.
While Eclipse in its own right is a great IDE with a rich ecosystem, following are some aspects that have endeared IntelliJ to me.
- Context-aware code completion
- Native support for Groovy language (third party plugin not required, e.g. Groovy-Eclipse for language support in Eclipse)
- Native support for running Spock Framework specifications (including executing individual features within a specification)
- Easily download libraries from Maven repository (and linking them to the project)
- Simplified approach to include CPI libraries in project’s build path
In the following sections of this post, I will show how you can set up IntelliJ for your own Groovy developments.
Since IntelliJ IDEA and Groovy are running on Java, you will need a JDK installed on your local machine (if it’s not already there). Since CPI is now running on Java 8, JDK 8 would be a suitable choice.
And of course, you will need to install IntelliJ IDEA as well – the free Community Edition would suffice.
Installation is straightforward, and you can accept the default settings (or tweak them according to your preferences).
IntelliJ Project & Module Setup
After the installation, we will begin with creating a new IntelliJ project to house all the development related files. An IntelliJ project is similar to a workspace in Eclipse (refer IntelliJ IDEA vs Eclipse terminology for further details).
A new project can be created via the Create New Project quick link on the Welcome screen or through File > New > Project menu item.
Select Groovy as the project type.
Once you have a skeleton IntelliJ project, you can then proceed to import CPI developments into it. Each CPI integration flow will be imported as a Module in the IntelliJ project.
As a demo example, the following Integration Flow is created in CPI with just a single step containing the default generated Groovy script.
Download the contents of the Integration Flow from Web UI.
Extract the ZIP file, and move it to the directory of the IntelliJ project.
Next, import the module using File > New > Module from Existing Sources.
Navigate to the directory containing the extracted CPI Integration Flow, and import the module as an Eclipse model. Accept all the default settings provided by the import wizard.
Once the module has been imported successfully, it will have the following directory structure.
As mentioned earlier, adding libraries is one aspect of IntelliJ that particularly stands out compared to Eclipse.
In order to proceed with local development of Groovy scripts in IntelliJ, we would need the following libraries included as dependencies of the module.
- Groovy SDK
- Spock Framework
- CPI libraries
The first two are available from the public Maven repository, while the last one needs to be retrieved from the CPI tenant following the approach detailed in my earlier blog post.
In Eclipse, for non-Maven projects, libraries have to be manually downloaded and added into the classpath. However, IntelliJ provides a handy functionality to automatically download Maven libraries and link them to the IntelliJ project/module.
Go to File > Project Structure. Select Global Libraries, then the “+” button to add a new Global Library from Maven.
Enter org.codehaus.groovy:groovy-all:2.4.12 in the input field, and press OK. This will automatically download the library for Groovy version 2.4.12 (version of Groovy used in CPI at the time of writing) from the public Maven repository.
Once the library has been downloaded, choose the module to add it to.
Back at the Project Structure screen, the downloaded JAR file will be shown.
Repeat the steps above for org.spockframework:spock-core:1.3-groovy-2.4. Spock includes Groovy library, so we need to remove the groovy-all JAR file to prevent conflict with the previous Groovy library.
Local Java libraries
For local JAR files, instead of manually adding each file to the classpath, IntelliJ provides a simplified approach to include a directory containing all the JAR files as a Global Library. The Global Library will be monitored by IntelliJ, and any file changes (additions, deletions) are automatically reflected in the classpath.
Select Global Libraries, then the “+” button to add a new Java Global Library.
Select the directory containing the retrieved CPI libraries to create the Global Library, and subsequently add it to the module.
Next, we need to set the SDK (equivalent to JRE in Eclipse) – Go to Modules, select the Sample1 Module, and click on the Dependencies tab. Initially, it would have no SDK configured, so select the Project SDK for it.
Finally, we need to indicate the directory containing the Groovy source codes. Change to the Sources tab, select root directory and mark it as a sources root.
At this point, if we build the project, the compilation would now be successful. Return to the main view by closing the Project Structure window, then select Build > Build Project.
The Fun Begins 🙂
Now that the (lengthy) setup has been completed, we can start enjoying the benefits of the IDE.
Source Code Assist
To start off, just by viewing the default Groovy script in the IDE, it already provides some suggestions for potential improvements to the code.
To quickly clean up the code, we execute the following commands:-
Code > Optimize Imports
Analyze > Code Cleanup
Local Standalone Testing
To execute local standalone testing, we will use the tester script provided in my earlier post (link here).
First of all, create a new package – right click the root directory of the module, then select New > Package.
Enter src.test.groovy as the package name.
Next, right click on the newly created package and select New > Groovy Script and enter the name of the script.
Copy the source code listing and paste it into the new script – make sure to modify the content for the package and location of the script under test.
Right click on the Tester.groovy, and select Run ‘Tester’.
The first run will fail with an error indicating the script under test is missing. This needs to be fixed by changing the working directory.
Remove src\test\groovy from the working directory, so that it is the root directory of the module.
Now, rerun the test and it should be successful, with the results shown in the bottom console.
Next we can introduce Spock for unit testing following approach described in CPI’s Groovy meets Spock – To boldly test where none has tested before.
To create a Spock Specification, right click on the src.test.groovy package and select New > Groovy Class. Enter GroovyScriptSpecification as name of the class.
Copy the source code listing from GitHub repository here and paste it into the new class – make sure to modify the content for the package and location of the script under test.
As mentioned earlier, IntelliJ provides native support for Spock allowing easy execution of the whole specification or individual tests.
Once the specification/test is executed, the results are shown in the bottom console.
For those who spend significant time and effort working on Groovy scripts in CPI, it is worth exploring IntelliJ IDEA as the development environment. While the initial setup might seem a little lengthy, it is a one-off activity and once completed, you can benefit from the productivity boosts provided by the IDE.
While I have listed some benefits of IntelliJ, it is not meant to be exhaustive as there are many other features that enhance one’s development experience – code inspection, debugging and version control just to name a few. This blog post serves as an introduction to the usage of IntelliJ and I encourage the reader to explore more.
Thank you for this article, it's very interesting.
If you remember we talked about migrate entire CPI from Eclipse to IntelliJ novembre 2018 after webUI interface was choice like mainstream of new implementation of CPI.
This could be an incentive for this way 🙂
Thanks for your comment. Yes, I remember several of our conversations around Eclipse, WebUI and IntelliJ.
For areas like Groovy development, version management, I have switched fully to using IntelliJ, but Integration Flow modelling still needs to be done on WebUI - so can't really migrate everything to IntelliJ yet.
Hi Eng Swee,
thanks for the great blog post!
Do you have any information on how to retrieve the API jar for mapping?
E.g. when a groovy script is used to extend the standard message mapping other classes can be used (like MessageContext - https://help.sap.com/doc/d47441d304c14a0ab9d3986c1b553a1e/Cloud/en-US/com/sap/it/api/mapping/MappingContext.html or Output - https://help.sap.com/doc/d47441d304c14a0ab9d3986c1b553a1e/Cloud/en-US/com/sap/it/api/mapping/Output.html)
However, if such a project is imported to IntelliJ the build fails, as the mentioned classes cannot be found (a library is missing). I wasn't able to find the jar file for this library.
The Mapping API is listed in the help document: https://help.sap.com/viewer/368c481cd6954bdfa5d0435479fd4eaf/Cloud/en-US/c5c7933b77ba46dbaa9a2c1576dbb381.html
Unfortunately, the JAR file containing com.sap.it.api.mapping.MappingContext is not one of the publicly available files in SAP's Development Tools site.
Alternatively, you can consider approaches as detailed in following blog posts:-
Furthermore, in light of recent blog posts like I *heart* Groovy mapping and I *heart* XSLT mappings, you might want to reconsider if using message mapping is the way to go.
Hi Eng Swee Yeoh
I am having issues with the com.sap.gateway.ip.core.customdev.processor.MessageImpl class.
Unable to resolve class
I have fished it btw.
Fully qualified class name: com.sap.gateway.ip.core.customdev.processor.MessageImpl
JAR file containing class file: jar:bundle://340.0:0/!/
I downloaded the jar and imported as reference
Could you please advise?
Try fishing for the following 7 files.
Hi Eng Swee,
I tried getting the jars using Ariel M. Bravo Ayala's great IFlow from his blog Exploring-cpis-filesystems-content/, but somehow the plugins directory is not available (visible?) and so I cannot download the jars.
Am I doing something wrong?
With the change to Apache Karaf and Java 8, the plugins directory is no longer available.
Have a look at my comment in the following blog post on the new approach to find the location for the JAR bundles.
Hi Eng Swee,
Thanks for your reply.
I guess I am in for some searching, because 561 contains a different jar nowadays:
The bundle number is dynamically assigned by the OSGi framework used in CPI/Karaf. A particular class will not always belong to a fixed bundle number like 561.
May I know what is the logic in the script that you used to arrive at this?
Dynamically assigned, nice ?
I used the iFlow from this blog https://blogs.sap.com/2019/01/03/exploring-cpis-filesystems-content/ to browse the directories.
Did you manage to get this sored in the end? I'm in a similar place where I've downloaded the bundle.jar from our tenant but getting an error when I go to run a test. As far as I can tell the class is part of the bundle...
When tester script is run:
In the end I did get it working because Eng Swee helped me at the TechEd.
But nowadays it is a bit easier, you can use the script library from the SAP CPI tools site.
I would highly recommend the E-Bite that Eng Swee and Vadim wrote on groovy scripting. In there it is explained step-by-step how you can set up IntelliJ IDEA so that you can use it to test Groovy scripts.
You can find more on this in this blog:
Perfect, I'll check that out, thanks so much Martin! 🙂
How do you deploy the Groovy script into the IFlow?
Can you send the relevant JAR package, com.sap.script.customs-development email@example.com