Paul Hammant's Blog: Bytedeco: A Portal Dedicated To Calling C++ Libraries From Java
Samuel Audet is perfecting a “call C++ library code from Java” facility. It’s some technologies (JavaCPP) and the creation of bindings to some well-known C++ libraries that pre-existed this exercise, using JavaCPP. These, for the most part, are heavy-lifting libraries that Samuel needs for his job. Bytedeco is the portal that pulls all this work of his together.
He’s made it easy for people to understand what he’s done, and how to use it. From there, Samuel hopes that others will contribute bindings to other well-known C++ libraries/frameworks.
- JavaCPP (on Github). This is the base technology that provides a number of tools to call into C++ code with the minimum of Java to be written. You can hand-craft bindings or generate them (possible bugs ahead) from the C++ header source files.
- JavaCPP-Presets (on Github). This is a growing index of low-level Java bindings to well-known C++ pieces.
- JavaCV (on Github). This is a layer of Java work to make for more elegant usage of some of the preset bindings around “Computer Vision”.
JavaCPP itself is a GPL (with the linking exception), which is pretty much like LGPL, and quite permissive.
Peering into the history of Java, package and library dependency systems, allows us to understand why Java is late in 2014 to this party. Some of this is just my opinion, or what I felt as I witnessed events.
Maven created a huge wealth of Java pieces for developers to consume. These are mostly pure Java, but a few like JRuby contain platform specific code that activates appropriately. Whether Maven is your build technology or not, the public repository that it created in 2002, is a defacto standard. Historically, the Java community has not significantly delved into C++ for heavy lifting.
Bytedeco’s components interoperate well within the Maven ecosystem.
At an operating system level, the Mac’s Homebrew system, is a beautiful package manager, that taking over from it’s predecessors (Fink and MacPorts). It marshals its brews in Git and on Github in particular. Git’s pull-request workflow makes it easy for others to contribute brews for new pieces, or donate fixes for those already made. Being a package manager at the OS level, it’s agnostic to the languages used, and is just about making things available to end-users on the Mac (albeit a lot of those would be command-line focussed).
Ruby has Gems, Python has PyPI, PHP has Pear, Perl has CPAN. All of these are indexes/repositories of simple language bindings to C++ that do heavy lifting, for these dynamic and traditionally interpreted languages. If an item exists as usable C++, it is not the culture of these communities to rewrite things systematically in their script language. Calling out to C++ was regular, for other languages. Perhaps too, was choosing to write in C++ for speed, and simultaneously make bindings for the preferred choice of Ruby/Python/Perl/PHP etc.
That’s a contrast to the view from 1997 onwards that missing Java-ecosystem pieces would be written from scratch in Java. A lot of developers retooled to be Java developers (1995-2001), or arrived in professional development with Java as their main language. Sun (Oracle now), wrote lower level things in the JVM in C++, and some library pieces in the java.* packages that bound to C++, but few enterprise developers ever did.
In 2004, when Rails put Ruby on the global map, there was the beginning of a second wave of people into the Ruby community - those whose principal language up to that moment was Java. These developers were much less capable with C++. Unrelated but correlated, they missed a few components from Java-land in their stack. Some of the early work by Java-escapees into that world was ports of Java pieces into 100% Ruby. Very soon after the same developers would make Gems would be more idiomatic to Ruby, but still not lean on C++ for heavy lifting by default. Back then, with Ruby’s performance much less than what it is now, you could claim that the very deep stacks were not helping Ruby processes handle more load.
Colleague Shantanu Tushar tells me the Python developer landscape, over the same time span, was in a similar situation as well.
Bytedeco could easily become a larger portal for bindings to pre-existing C++ pieces. Most likely those pieces are already depended on by other dynamic languages, and Java application is late taking advantage.
Oracle also have a Foreign Function Interface (JEP 191) that is trying to improve on the base JVM technologies for interop with non-JVM code. That page details the complexities of developing such things. JavaCPP generates the appropriate Java bindings, and would probably be able to take advantage of the JEP 191 if it comes into being.