I am writing a baseball statistics application. It is called StatMantis and it’s another in a long line of personal projects I’ll probably never finish. It contains many statistics which have equations that deserve to be in the javadocs. After I researched all the possible ways to accomplish this and I settled on MathML. For example, in my Batting Average On Balls In Play (BABIP) statistic, there is a formula. I wanted one of those badass formula displays like Wikipedia has. So I had javadoc on the class that looked like this:

I noticed several projects out there that I could utilize to put a MathML equation in my javadoc. JEuclid was my first choice. It could output to an AWT image. It could even given me information to generate an image map to link to the other factors in the equation. But I would have to hack up the standard Sun (…er…Oracle) doclet and do mass hackery for this simple thing. I decided it wasn’t worth the effort since the javadoc tool is difficult to extend. Hopefully one day a project like javadoc-ng will get finished and solve my problems (wink wink, sorry if you’re still waiting on me Harmony guys). So after I couldn’t find anything I liked on the MathML implementations page I almost gave up. I couldn’t find any that were interactive and cross browser. I specifically wanted the href feature of the MathML 3 spec so I could link to my other classes.

Then I found MathJax and it looked like it would solve all my problems. So the first thing I did was toss it in the <footer> element of the javadoc ant task. The distribution is extremely large, and yes you need just about all of it. So I put MathJax in there and edited config/MathJax.js. I changed jax: ["input/TeX","output/HTML-CSS"] to jax: ["input/MathML", "output/HTML-CSS"] and extensions: ["tex2jax.js"] to extensions: ["mml2jax.js"]. This is needed because the input is MathML, not TeX. Once the config was changed, I added the following in my javadoc ant task:

I put this in the footer, because it seems like the header is rendered twice, which isn’t cool. Also, per the javadoc footer documentation I have to escape the quotes. The {@docroot} makes sure it sets the relative links properly. Once I executed this I was very happy to see my formula appear properly.

Now I wanted to link each part of the equation to its representative class. My first approach was to utilize the inline {@link} tag. This outputs a code tag wrapped in an anchor tag which links the piece. I wrote at least a dozen different javascript functions to pull the href out of the anchor and put it on the <mi> tag and move the text out from inside the code tag. Everything I tried ended up in extreme failure because IE sucks balls. Specifically, I can’t edit my math tags via DOM because IE doesn’t understand it. I also couldn’t insert a manipulated MathML string as innerHTML on the parent, because it trimmed off pieces for no reason.

So I decided that I needed another, non-client side approach to having links. Post processing the HTML was my first guess, but that is not a very elegant solution. So I decided to extend Javadoc w/ a custom Taglet. I tried to find the existing Taglet that Sun built for {@link} so I could use the same algorithm to obtain the URL, but it’s not there. They get the benefit of having everything there including the RootDoc. So I wrote my own Taglet and tried it in many scenarios. I quickly realized I would not be able to link to all possible methods/fields because the Taglet interface simply doesn’t provide enough information. Similarly, I can’t validate the values entered in my taglet either. Without further ado, here is the custom Taglet (collapsed by default):

It works only for class/interface references and doesn’t do any real validation. Regardless, it solves my problem perfectly, and now my mathematical formulas appear in my javadoc complete with links to other classes. Check out the build-javadoc target in the ANT script to see how to include it in the javadoc task. Overall, it works well and I am happy with it. Here is what the aforementioned BABIP javadoc looks like now:

The Eclipse custom dictionary is a simple file listing all words to ignore when spell checking your comments. Below is an excerpt from mine. Of course, these are only inline comments, never javadoc. This is mostly for my personal projects (that I may keep a little less than professional). In my opinion, these should be part of the standard Eclipse dictionary anyways 🙂

When using SWIG with Java, I quickly realized that there were wasn’t support for std::set or std::list and only minimal support for std::map and std::vector (i.e. no proper iteration). Other languages (python, ruby, etc) had std_set.i and std_list.i whereas Java does not. I am not a C++ expert and definitely not an expert at writing SWIG typemaps.

My only solution was to write C++ wrappers for these collections. For some I also needed iterator wrappers to support their Java counterparts. They are listed below (collapsed by default).

Basically all these do is provide SWIG-readable methods for the underlying collections. Again, I am not a C++ expert and I only have minimal test cases to prove to me they work. These headers should be “%import”ed in your SWIG interface.

Now I need to wrap these in normal Java collections. I use std::map, std::set, and std::vector in Java as a Map, Set, and List respectively. In STL, std::list is not indexed and therefore must also be mapped to a Set. Note, this violates the Java contract of a Set where it is assumed that all elements are unique. I suppose I could I have used a Queue or an AbstractSequentialList, but I’ll stick w/ Set for now (iteration is still in order).

We’ll assume MyObject was generated by SWIG as the class name MyObject and your std::list was generated by SWIG as the class name SWIGTYPE_p_std__listT_MyObject_p_t. We’ll also assume your original std::list can be obtained via mymodule.getMyObjectList(). Including the above, you should now have two more classes: MyObjectListWrapper and MyObjectListIterator. Now you can either instantiate the NativeSet directly like so:

We’ll assume MyObject was generated by SWIG as the class name MyObject and your std::map was generated by SWIG as the class name SWIGTYPE_p_std__mapT_std__string_MyObject_p_t. We’ll also assume your original std::map can be obtained via mymodule.getMyObjectMap(). Including the above, you should now have two more classes: MyObjectMapWrapper and MyObjectMapIterator. Now you can either instantiate the NativeMap directly like so:

We’ll assume MyObject was generated by SWIG as the class name MyObject and your std::set was generated by SWIG as the class name SWIGTYPE_p_std__setT_MyObject_p_t. We’ll also assume your original std::set can be obtained via mymodule.getMyObjectSet(). Including the above, you should now have two more classes: MyObjectSetWrapper and MyObjectSetIterator. Now you can either instantiate the NativeSet directly like so:

or you can extend NativeSet and call the super constructor with these values.

std::vector – Since a vector is indexed, an iterator is not needed here. Suppose we have the following C++ reference:

std::vector<MyObject*>

Therefore you would need a %template set for the VectorWrapper class (in VectorWrapper.h above) like so:

%template (MyObjectVectorWrapper) VectorWrapper<MyObject*>;

We’ll assume MyObject was generated by SWIG as the class name MyObject and your std::vector was generated by SWIG as the class name SWIGTYPE_p_std__vectorT_MyObject_p_t. We’ll also assume your original std::vector can be obtained via mymodule.getMyObjectVector(). Including the above, you should now have another class: MyObjectVectorWrapper. Now you can either instantiate the NativeList directly like so:

or you can extend NativeList and call the super constructor with these values.

Now you have Java collections representing your STL collections directly. There are several things to note:

Pointers – These collections use the underlying pointers. Therefore, altering a collection here will alter the source collection. Also, since my examples use MyObject as a pointer, they will also be altered by users of this collection. If you don’t want this, instantiate your favorite version of the collection and pass this collection as the parameter; this does a copy

Garbage Collection – Using mutable collections like this can have an issue with SWIG memory ownership. Make sure you read up on SWIG memory management. If you add an object created in Java to this collection, SWIG automatically assumes it owns the collection of this object. Since there will be no references to the object inside of Java, the object may get garbage collected. I usually call Collections.unmodifiable* on this collection because it’s rare I need it changed. Otherwise, you probably instantiated the native collection object in Java too and it should be OK then.

Performance – These collections extend AbstractList, AbstractMap, and AbstractSet. With AbstractList, doing things like remove and contains with the actual object iterate over the entire object. The other two abstracts have similar mechanisms for other pieces. For all collections, equals() iterates through all. Please reference the base classes to understand what they do. If I wasn’t lazy right now, I’d have focused on bridging all STL methods and implement better RandomAccess.

Errors – I only tested a few pieces for right now. I haven’t tested with null objects, or doing things like calling iterator.next() if iterator.hasNext() is false. I purposefully didn’t implement iterator.remove(). Good luck 🙂

Thread safety – I have no clue! Be safe and use Collections.synchronized*.

Remember, none of this is tested that well and I’m not the strongest C++ dev around so use at your own risk. Once I complete and open source my library that uses this, I will link to the full code and test cases. I hope this code helps someone. License: WTFPL.

I am working on a project where my DLL is loaded as a dynamic plugin in a third party application. I wanted to use Java to accomplish my task so I chose to use SWIG with the Invocation API. Luckily, I can guarantee a single execution platform: Windoze. I am no C++ expert, but here’s how I accomplished this…

I will put all my JARs on the same path as the DLL, so I grabbed the current DLL directory using the HMODULE in the DllMain like so:

Now that I can get all JARs, I instantiate the JVM in a constructor of my “management” class. I have to first load the JVM DLL because it won’t be loaded by default. I use the JAVA_HOME environment variable to locate the DLL. The code is similar to the following:

After compiling this into a DLL along w/ a test method to call back to Java, I went ahead and ran SWIG on the includes I was writing the plugin for. Unfortunately, none of the Java native methods were mapped. It turns out that, when instantiating the VM from native code, none of the JNI methods are “registered”. RegisterNatives to the rescue. The C++ API I was using generated several thousand Java methods in SWIG making it much to trivial to hand write the RegisterNatives code. So, I made an ANT task to do it for me. Here’s the code (collapsed by default):

NOTE: I wouldn’t use the JNI signature generator above in other situation; it doesn’t handle arrays.

It accepts three arguments. The “source” argument is the path to the .cpp file (the -o argument passed to SWIG). The “module” argument is the SWIG module name in your .i file. The “package” argument is the package you told SWIG about (the -package argument for SWIG).

It reflectively obtains all native methods in the ‘module + JNI’.java file. This means the generated SWIG code must be on the classpath when running this task. It creates a SwigUtils class in the header file with one method: registerNatives which accepts a JNIEnv:

class SwigUtils {
public:
static int registerNatives(JNIEnv* env);
};

In the cpp file, it implements this method at the bottom with all the other SWIG code. The method returns the value returned by RegisterNatives. Now all you have to do is call this once you are done creating your JVM: