This page describes how our development environment for creating CAM modules operates.
Setting up a development environment and build process
The CAM development environment we use is based on NetBeans. We highly recommend following the same approach, since CAM is modular software and has a relatively complex build process. We have worked out a reasonably efficient and reliable way of doing it, which is detailed below.
In addition, NetBeans has an excellent tool for building graphical user interfaces (GUIs) in Java. However, it is also possible to develop CAM plugins using Eclipse or other IDEs - please contact us if you would like advice on doing so.
Installing everything
Our development and build process is based on NetBeans. To install the various bits and pieces on a Windows system:
- Download and install the latest Java SE Development Kit (JDK, at least version 1.8) from here
- Download and install the latest NetBeans IDE from here
- Create a folder somewhere on your computer where the build environment will live. We use C:\cam-dev
- Download the CAM distribution and unpack it into that folder. So the location of the CAM.bat startup script should be: C:\cam-dev\cam\CAM.bat
- Note that the directory structure is critical to developing CAM modules, for reasons which will be explained below.
- Open NetBeans and create a new project, which will contain the source code for your plugin. The following instructions assume that the project is named my-plugin. Ensure that 1) the project is of type Java Class Library; and 2) the project folder is located within the cam-dev directory, After doing this the folder structure should look something like:
C:\cam-dev
- cam
- my-plugin
If you browse this within windows explorer, in the my-plugin folder you should see the contents of your netbeans project - including the sub-folders src, dist, build and the build script build.xml. NetBeans creates all Java source files within the src folder. When you compile your project, it follows the instructions in build.xml to create a .jar file which will be located in the my-plugin/dist folder (build.xml is actually an ant script; for more information see the Netbeans documentation)
Configuring the build and run actions for the new project
CAM is a modular program which assembles itself dynamically on start-up. It looks in the modules directory and dynamically links all the files it finds, based on instructions within each file. The files with .jar extension are all created and updated using the NetBeans compilation process.
To make a new NetBeans project, sucvh as that created above, work as a CAM module, follow these steps: (N.B. you will have to do this for each separate NetBeans project you use to create CAM modules - although a single project, and thus a single .jar file, can contain multiple plugins.)
- Open the build.xml file in the project. The file is located in the root folder of the NetBeans project; in this case c:/cam-dev/my-plugin/build.xml. You can access it using a text editor such as wordpad or can find it directly in NetBeans by clicking the Files tab at the top-left corner of the screen.
- Paste the following two segments of XML at the end of the build.xml file (just before "</project>"). The first code segment copies the compiled JAR file to CAM's modules directory and deletes temporary files after you compile the project in Netbeans, and the second overrides the "run" button in Netbeans to start CAM rather than running the project.
- Note: to make this work, you will need to create a 'dummy' main method somewhere in your project. NetBeans will ask you to choose the main class for the project, so pick the 'dummy' class you created - once you've done so, the change you made to build.xml will cause it to ignore your choice and run CAM anyway.
<!-- after building, copy the jar file to the 'modules' directory of the main CAM distribution and delete the unnecessary "lib" directory to save space -->
<target name="-post-jar">
<copy todir="../cam/modules">
<fileset dir="dist">
<include name="*.jar" />
</fileset>
</copy>
<delete dir="dist/lib" />
</target>
<!-- run the main CAM distribution -->
<target name="run">
<exec dir="../cam" executable="cmd">
<arg line="/c cam.bat" />
</exec>
</target>
After making this change, two things should happen:
- When you build the project in NetBeans, the .jar file containing the compiled code will be copied into the modules directory of the cam folder. It will be called my-plugin.jar. Build the new project and check the .jar file appears in the modules directory before proceeding further.
- When you run the project in NetBeans, the CAM.bat startup script will be used and CAM should start. It will try to link in your new module which is now present in the modules directory. At this stage the linking will fail, since configuration is not yet complete; however CAM should start regardless. You should see the output of the CAM script appear in the NetBeans Output pane, at the bottom of the NetBeans window. You will probably see a lot of non-critical error and warning messages.
Adding CAM's libraries to the project's classpath
Any plugin you write will have to use one or more of the classes defined in the CAM core distribution.This is because the plugin will need to interact with the main system, by implementing an abstract method (a "plugin point method" in CAM terminology) which defines where the code will interface with the CAM software. Your plugin will probably also need to call several methods (subroutines) within the main CAM distribution - for instance, you may need to use these methods to access the model's data structures in order to perform some sort of analysis. For example, in a task-based simulation a plugin will usually access the list of tasks and their interconnections created by a modeller, in order to set up the simulation data structures.
To be able to access these methods in CAM, you will need to add the relevant .jar files (which are part of the CAM distribution, located in the c:/cam-dev/cam/modules folder) to your project's classpath before it will compile. For most projects, you will need:
- p3-dynamic-library-loader.jar
- p3-core.jar
- p3-default.jar
- asm-core.jar
- jdom.jar (not specific to CAM, but distributed with it)
To do this in NetBeans:
- Right-click on the project in the pane on the left-hand side of the screen and choose "Properties"
- Choose "Libraries" in the tree on the left-hand side of the screen
- On the "Compile" tab click "Add JAR/Folder"
- Browse to the modules directory in the cam folder
- Select the .jar files you want to add and click "Open". You may want to choose "Relative path" from the options for "Reference as:" on the right-hand side of the window, so that your project will not lose track of the libraries if you move the cam-dev folder to a different location on your computer.
If your project also uses the data analysis facilities of CAM, by generating datasets and/or defining ValueProviders, you will also need:
- p3-simulation-results-explorer.jar
Other plugins may need other files - please contact us if you require more information or help in configuring your compilation. Usually you can just add all the files in the modules folder; this will ensure your code will compile.
You are now ready to begin development of the plugin code. See here for more information.
Using other features of NetBeans
More advanced developers might wish to:
Use a debugger: Run CAM using the cam-debug.bat batch file, not the usual cam.bat file. This causes the Java Virtual Machine to allow debuggers to attach to it using the "Shared Memory" method with the name "p3" - in NetBeans, do “Attach debugger”, choose JPDA debugger, transport SharedMemoryAttach, and set the name to ”p3”.
Use a profiler: NetBeans supports "dynamic profiling" for Java 1.6 and above, where you can connect a profiler to a running Java application. However, if your TMP directory is on a FAT32 filesystem, performance monitoring files are not being created for security reasons by default (if you follow through the wizard for "Attach Mode" you will see "<Error Getting Running Processes>" rather than an entry for CAM). One solution is to add the command line argument "-XX:+PerfBypassFileSystemCheck" to the .bat/.sh file used when starting CAM. More information:
http://www.javapassion.com/handsonlabs/nbprofilermemory/
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5042659
http://java.sun.com/performance/jvmstat/faq.html#4