A tutorial on how to set up a Maven project to manage and prepare external dependencies to be used with Anylogic.
This is a special guest blog post by Guilherme Coelho. We asked Guilherme if he could write about the use of Maven in an AnyLogic post after an insightful answer from him to a question posted in AnyLogic Software User Group on LinkedIn.
Pre-requisites: This article covers some advanced aspects of Java programming, Anylogic, and dependencies management. Before continuing, make sure you understand how to add and import external dependencies to Anylogic.
Even though Anylogic comes with a wide set of tools to build simulation models, every now and then, and more often than expected, you might face the need to use some very specific libraries to do matrix calculations, optimize vehicle routes (see my presentation on the 2021 Anylogic Conference), or even to connect some external solver to perform decision making during the simulation.
If it comes to that, one might be tempted to just download and place the JAR files to the model root folder, and then add them to the Anylogic model dependencies list, as instructed in Anylogic Help. Even though it works just fine for very small projects, it can become troublesome really fast as the project grows in size and complexity.
A best practice in software development is to use some dependency management tool to handle the entire process. This kind of tool is responsible for ensuring that we automatically get exactly the right version of all necessary dependencies before building or installing the software being developed.
Without them, in the worst-case scenario, one might have to manually download all the project's dependencies and also the dependencies' dependencies, which will absolutely pollute the project repository with unnecessary files. For more on this topic, check this post.
Since Anylogic uses Java as a programming language, for the sake of this article, I will cover how to set up a Maven project for dependency management. Maven is one of the most popular dependency management tools out there in the Java world.
Also, we will be using the "External JAR files" model that is available inside AnyLogic. You can locate it here: Example Models > Models from 'The Big Book of Simulation' > Java for Anylogic users.
This model has the simple purpose of teaching us how to add the Jama linear algebra package to the model and perform matrix multiplication.
Initial setup
Before we can actually begin, make sure that you have everything installed and ready to go. So, follow the steps:
1) Download and install the Java Development Kit (JDK) and make sure that the JAVA_HOME and PATH environment variables are set accordingly.
On Windows
Open up the system properties (WinKey + Pause), select the “Advanced” tab, and the “Environment Variables” button. On the top section, you will see all environment variables related to your user. Add a new variable called JAVA_HOME and point it to the JDK installation path. Finally, make sure that the PATH variable is also pointing to the JDK's bin folder.
On Mac
Read through the instructions here
2. Download and install Maven. To install it, unpack its contents anywhere on your machine and add the bin folder to the PATH variable the same way you did before.
Creating the Maven project
With everything set up, we can go ahead and create a new Maven project. The next steps can be done with any IDE that supports Java and Maven projects, such as VScode or IntelliJ.
For this article we will use VScode, so make sure you have it installed. Search and install the "Maven for Java" extension from the VScode Extensions tab.
Next, open the Command Palette and look for the "Maven: Create Maven Project" command. This will prompt some user inputs:
Select your project's archetype. We recommend selecting the most simple one such as the "maven-archetype-quickstart".
Select the most recent archetype version.
Define the project's group Id. The group Id is somewhat like a package namespace.
Define the artifact Id. The artifact Id should be your model's name. It will also be the name of the folder that will be created for the project.
Select where the project's folder shall be placed.
[On the CLI] Enter your project's version and hit "Y" to confirm all the definitions and finish the project creation wizard.
Open the created folder with VScode. Inside it, there will be a 'src' folder and the 'pom.xml' file.
We will not need the 'src' folder since we are not building anything outside Anylogic, so just delete it.
Setting up the configuration file
In the POM file, find the <dependencies> section. Here, you must add all the dependencies of your project. In our case, we need to add only the following:
<dependency>
<groupId>gov.nist.math</groupId>
<artifactId>jama</artifactId>
<version>1.0.2</version>
</dependency>
Note that you must inform the group Id, artifact Id and version of the package. With that, Maven will know which package and version it should pull from the Maven Repository to your local machine.
Actually, as of March 2022, there is an update available on this package. If you would like to update to the newest version, just change 1.0.2 to 1.0.3 in the <version> section.
Now, we need to tell Maven how to handle the dependencies after pulling them. By default, Maven will download the JAR files but it will not place them on the project's folder, therefore we must include and configure a plugin for that purpose. Right after the beginning of the <build> section and before the <pluginManagement> section, add the following:
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/libs</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
...
With that, all the dependencies will be placed in a new folder called 'libs' which will be located in the project root. You can also change the destination folder by changing the <outputDirectory> section. For more details on this, see refer to the documentation.
Attention: If you chose to keep the 'src' folder, make sure to not delete junit from the <dependencies> section, otherwise the next steps will not be successful.
Pulling the dependencies
With everything set up, all it is left to do is to order Maven to pull the dependencies and put them in the right place. To do so, just run the command on your CLI:
mvn clean install
This command will make sure that any previous build directories are deleted before the new installation process. Downloading everything might take some time, so just wait a few seconds for the pipeline to finish.
If all is ok, you should see a message like the one below and a new folder called 'libs' created in your project's directory with the 'jama-1.0.2.jar' file in it.
You will need to run this every time you add new dependencies or if you want use newer versions of some of your dependencies. The great thing is that you don't need to worry about whether the latest version of some library you use is now dependent on some other library. Maven avoids the need to discover and specify the libraries that your own dependencies require by including transitive dependencies automatically. This is the key reason why it is used by professional and advanced software developers (and simulation modelers)
Finally... back to Anylogic
Back to the Anylogic "External JAR files" model, we need to replace the Jama dependency with the one that was just downloaded. To do so, first delete the previous one, then add a new dependency pointing to the JAR file in the 'libs' folder. Browse for the file location and check the required options to access it from its original location with the "Use relative path" option selected.
Click on the Build Model button to check if everything is ok. At this point, you will be able to run your model without any issues. Congratulations!
Wrapping up
Remember, this solution may or may not be suited to your project. If you are at the starting phases of model development you probably would skip all these steps without any backlash. However, if your model grows or if you have to run it through an automated pipeline, there might be no escape.
Keep in mind that there are always other solutions to the same problem. You just need to balance the pros and cons of each one.
Finally, to make things easier for everyone, I have prepared a Github repository with everything covered in this article. Take a look in here.
Disclaimer: To write this article only open source/free software were used, along with Anylogic PLE.
Guilherme Coelho
Guilherme Coelho is a guest writer for the AnyLogic Modeler. Feel free to connect with him over LinkedIn.
P.S. Jaco-Ben will be using Maven in a future post about using Google OR-Tools inside AnyLogic to solve a vehicle routing problem. If you want to see a real-life example of how to use it, consider subscribing.
What next?
If you liked this post, you are welcome to read more posts by following the links above to similar posts. Why not subscribe to our blog or follow us on any of the social media accounts for future updates. The links are in the Menu bar at the top, or the footer at the bottom. You can also join the mobile app here!
If you want to contact us for some advice, maybe a potential partnership or project or just to say "Hi!", feel free to get in touch here and we will get back to you soon!