In the first part of this multi-part tutorial I present how OPAL – The OPen, extensible Analysis Library for Java bytecode – can be build (or integrated) to be used in your own static analysis project.
How to read this tutorial
In the first paragraphs of each section I will concentrate on the how of a specific task. If you are just interested in the doing and not in the why, you can always skip the last parts of a section. I read tutorials this way myself, so I will also present them in this fashion to make it easier to concentrate or get the details you want, whatever is better for you.
If I provide shell command examples, they always start with the $ sign representing the shell prompt. Only type in everything after that sign. Code or configuration examples might be snippets, so read carefully.
A current JDK is the prerequisite for almost everything Javaish. If you don’t have it, please install it.
Next, OPAL is written in Scala, so in order to compile itself or your analyses, you need Scala. We strongly encourage you to also install SBT – the Scala Build Tool. If not for OPAL then for your own project.
When you just want to use OPAL to implement your static analysis, the following section is for you. You are interested in working directly on OPAL? Then skip ahead to the section named “Working on OPAL”.
Using OPAL with Maven
Until a full version is released to maven central, you need to add the following repository definition for snapshots to your pom.xml.
<repositories> <repository> <id>snapshots-repo</id> <url>https://oss.sonatype.org/content/repositories/snapshots</url> <releases><enabled>false</enabled></releases> <snapshots><enabled>true</enabled></snapshots> </repository> </repositories>
Then you add the following dependency if you just need the bytecode toolkit:
<dependency> <groupId>de.opal-project</groupId> <artifactId>bytecode-toolkit_2.10</artifactId> <version>0.8.0-SNAPSHOT</version> </dependency>
Or if you need the complete abstract interpretation package you add instead:
<dependency> <groupId>de.opal-project</groupId> <artifactId>abstract-interpretation-framework_2.10</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
You can now use OPAL as part of your analysis project.
Using OPAL with SBT
You are writing your analysis with Scala? Great! You can just use SBT to do the same job as Maven. Just add the following to your SBT file:
scalaVersion := "2.10.4" resolvers += "Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots" libraryDependencies += "de.opal-project" % "bytecode-toolkit_2.10" % "0.8.0-SNAPSHOT"
Or if you want the full abstract interpretation package:
scalaVersion := "2.10.4" resolvers += "Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots" libraryDependencies += "de.opal-project" % "abstract-interpretation-framework_2.10" % "0.0.1-SNAPSHOT"
And now you are good to go!
Using OPAL from the build source code
That is also rather straight forward: Follow the instructions in the next section and afterwards make your Eclipse project depend on the OPAL projects you need.
Working on OPAL
In many cases it might be interesting to look at OPALs source code or even fork and modify it for your analysis. In this section we enable you to do so.
Getting the code
$ git clone https://bitbucket.org/delors/opal.git
Cloning into 'opal'... remote: Counting objects: 31433, done. remote: Compressing objects: 100% (8925/8925), done. remote: Total 31433 (delta 13663), reused 30444 (delta 12715) Receiving objects: 100% (31433/31433), 36.27 MiB | 5.06 MiB/s, done. Resolving deltas: 100% (13663/13663), done. Checking connectivity... done.
As you see in the above example, cloning the OPAL Repository is fairly easy. You know got everything you need.
Let’s take a moment and look at the structure. In the root folder of the repository, you have the file build.sbt and the project folder which contain the root build information, we will need later during compilation. The core and util folder contain the functionality to read and traverse the contents of Java class files. Michael Eichberg considers those two project folders as the most mature ones. In a later tutorial I will show you how to use this functionality effectively.
As usual, the incubation folder contains interesting but unfinished work. The ext folder contains several useful extensions in OPAL. In ext/ai you will find an implementation of an abstract interpretation framework. I will award possibly more than one post to this part of OPAL, as it is one of most flexible yet useful.
Whilst ext/dependencies and ext/findrealbugs show how OPAL can be used to find source code dependencies or implementation bug much like in FindBugs.
Compilation and update maintenance
So, you got the code and installed all the prerequisites… Great! Then the next thing you type is:
$ sbt copy-resources doc
This will compile all the sub-projects and will generate the ScalaDoc documentation for OPAL. This command is also very helpful, if you pulled new code from the repository.
If you are now curious that you actually downloaded and built a fully functional version of the code, just type the following line to execute the test suite:
$ sbt test
On some machines, you might encounter memory problem, that manifest themselves in those kind of messages:
[error] Could not run test de.tud.cs.st.bat.resolved.ai.project.CallGraphThreadSafetyTest: java.lang.OutOfMemoryError: Java heap space
You can easily allocate more memory to SBT by specifying a file in your home directory named .sbtconfig containing this line:
There you allocate up to 2GB of RAM to the SBT process. Please change this according to your system.
You should be greeted by a message much like this in the next run:
[info] All tests passed. [success] Total time: 209 s, completed ...
Depending on your taste in IDEs, you might consider Eclipse to be a good option… Well, we also do. So type just type:
$ sbt eclipse
SBT will now create you the necessary Eclipse project files and you can then add the projects to Eclipse using the menu File… Import… Existing Projects into Workspace. Point it to the checkout and let it import all projects you need.
If you pull a new version of the code from the repository, be sure to close Eclipse to avoid compilation races and execute the steps from section Compilation and update maintenance.