As a C++ developer, I occasionally come across Java libraries like iText, Batik, JasperReports, and JFreeChart. In each case, equivalent cross-platform C++ libraries seem to be much less mature, much more expensive, or unavailable.
Is it practical to use these Java libraries from my C++ app for reporting, charting, and similar? If so, what's the best approach to doing so?
Use JNI to embed a JVM within my application?
Use GCJ to compile the Java libraries to native code?
Some other integration method that I'm not aware of?
Give up, since calling a Java library from C++ would be too hard to be practical, and instead invest my efforts in finding C++ libraries?
The least complicated method of integration is the old-school UNIX approach: launch a small Java program that does the task you need and communicate with it on STDIN/STDOUT.
This may not be possible in all cases, but it definitely is for use cases like PDF, SVG, reporting and charting which largely involve generating single documents for saving or display.
Watch out for log4j, slf4j, JUL, etc. logging if you take this approach! Anything that the Java program writes to standard out could corrupt the document you receive in the C++ program. Disabling logging or using sockets may be better in that case.
Related
I have a compiler for a domain specific language that outputs a .net dll (that can then be used to do whatever the DSL said it should). It works well under .net but now I need to make the compiled dll functionality accessible from Java. The interface changes depending on the DSL, much like it would if I was implementing an F# type provider.
Ideally, I would like something along the lines of Reflection.Emit except that it would generate Java bytecode. It is important that the end-user can debug their Java code that uses my generated library from a Java GUI, so I don't think I can just use IKVM to instead include the Java code in .net. I also cannot use a commercial product such as JNBridge because all the users would need to install it, and call it every time their DSL code changes.
Is there a better solution than generating a .java file in text format and compiling it with a Java compiler? The .java file would just be a light-weight interface talking to the .net dll over some IPC mechanism (perhaps a named pipe), and its purpose would be to provide a typesafe interface similar to what would be seen from a .net application (except with indexers, getters, setters, overloads, etc replaced with some sort of horribly verbose syntax). Many thanks.
Java native interface is a way to call native code from Java (That dll isn't running on the JVM, thats for sure). Throw your dreams of "Write once run anywhere" in the bin now.
If you want to use dlls then you have to use JNI (or something similar or based on JNI like jni4net). It's not as pleasant as say, using c++ from c#, but it's pretty doable and far and away the best way to use dlls from java (I think the second best is re-writing the native code).
Alternatively you could run a windows process alongside your java app and soap/json/namedpipes/etc between the two, is that what you suggest in the last paragraph?
This would be odd for a small solution, but for a larger modular project it's not so crazy. I would recommend using sockets to communicate between the two, because I think sockets are easiest. It says client/server in the example, but it could be two processes (java and f#). ... This causes problems for performance, synchronisation, firewalls etc.. ahhh, just use JNI.
Just wondering if there are any Java implementations that work without a JVM. The reason I'm interested is, well, simply because I'm curious, and I was wondering if there were any "lightweight" Java implementations (without all the Sun libs attached).
I'm also interested in embedding Java in C++, but embedding the JVM in C++ seems rather ridiculous to me. I just want to exploit some of the Java language features in my C++ apps, but not exploit all the frivolous Java APIs.
EDIT:
I see from a lot of the answers I've gotten that I need to clarify...
I recently got in to developing node.js applications, which uses JavaScript. JavaScript in istelf is a language spec, it doesn't automatically come with the DOM, window.open, etc., although it did for a while. I'm wondering if there's something similar to Google's v8, except not for JavaScript, but for Java. In the end, I don't care if I can't write Hello World apps with it, I just want to be able to embed Java in a C++ application the way I can embed JavaScript in a C++ application with v8 or SpiderMonkey. If I could do that, then I could implement console output in C/C++ and then make that implementation callable from Java.
Do you want the Java VM alone without the API(STandard Library) ?
The JRE is composed by the JVM (Virtual MAchine) and the Standard Library, I have doubt that you can find a java implementation without the JVM ... You could find a compiler that compile java source code into native code(take a look at GCJ), but not a Java implementation without the VM.
Take a look at this wikipedia page to see some alternative Java implementations .
There's GCJ (GNU Compiler for Java), but the project has been deprecated since OpenJDK was open sourced.
there are light weight java processors designed for use in small devices for example JOP
As others have hinted, the "JVM" is the mechanism that knows how to load classes, interpret "bytecodes", and manage storage. It does not inherently include any of the java.lang... stuff, except that a few classes (String, Class, et al) are needed to represent classes and other basic data structures in the JVM.
As a result, Java without a JVM is just a bunch of meaningless bits.
There are (or were) compiled versions of Java that do/did not need the interpreter (though a reasonably compact interpreter is quite easy to build). A primitive class loader and some sort of storage management are still necessary, but class loading can be kept simple and for short-lived apps (or those that live with special restrictions) the storage manager need not do garbage collection.
As pstanton suggests, there are "lightweight" Java (or "Java-like") implementations that are suited for small devices.
IMHO, You need to re-exampine what it is you really want.
Java runtime consists of two main components
The JVM to run the code
The standard libraries which come with it.
You suggest you want to use Java, but you don't really have anything left without these.
For example, you cannot even write a "hello world" program without the libraries as String is a class in the JDK.
This is a general "noob" question about software design, so I apologise if it seems vague,
but I would really appreciate the advice. Note the system described below is purely an example, not a specific product I have in mind.
I often have a need to combine the functionality of several libraries or utilities, written in different languages. For example, if I want to code a high-performance audio processing application for the desktop, I will write it in C / C++. Then, I want to add a nice GUI. But I don't want to learn Qt. I like the look and feel of Adobe Air, and would like to use that. Later, I have a need to access a USB device. But the USB library I have only has an API in Java. How can I combine all these elements together, to take advantage of their relative strengths?
Clearly, I cannot compile these various elements into one single executable. So I need to create and run them seperately, and give them a means to communicate. The most common way to do this seems to be using IPC (Inter Process Communication), eg shared memory or sockets. I prefer the idea of sockets, as the programs could potentially run on seperate machines on a network.
So I decide to create a local client / server system, with a custom API, to allow these elements to communicate. For example, the Air application will receive a message from the C application, telling it to update it's UI. The USB application running in Java will use the sockets to stream audio from the USB hardware, into the C application.
My question : is using local sockets in this way a typical way to design such a system?
Will the performance be much worse than a truly native application (e.g. everything in Java or C, in a single executable) ? It also seems likely that such an approach would be prone to bugs, and difficult to maintain?
I frequently find myself coming up against the limits of existing software libraries (e.g. a graphics library with a pretty, flexible UI but no way to access low-level hardware, or a media library that can mix many audio streams, but has no support for video playback), and find it very frustrating. If anyone could advise the best way to combine arbitrary software libraries like this, I would really appreciate it.
Thanks in advance!
As you have correctly identified, combining libraries from different language or platforms is hard. There are several ways to do it, but none are ideal. Examples:
Native call interfaces (e.g. JNI / JNA) - very fast but tricky to make work correctly, and you have the problem that the data types used typically don't map cleanly across different platforms. Adds native dependencies.
Socket based IPC with text protocol (XML, JSON, etc) - works OK and common formats are likely to be supported at both ends, but adds a lot of overhead. Can be a pain to maintain custom schema mappings etc.
Socket based IPC with binary protocol (e.g. Google protocol buffers) - quite efficient, needs a lot of work to get a custom protocol working correctly on both ends
Communication via a 3rd system (e.g. database, message queue, filesystem) - lots of overhead, can get fragile, introduces a major dependency on a 3rd system.
In my experience, it usually isn't worth integrating a new language / platform just to get one specific library or feature. Take your user interface example - no matter how nice Adobe Air looks, I doubt it is worth trying to integrate it with an existing C/C++ application.
Even if you get it to work, it will significantly complicate the future maintenance and devlopment of your application. Builds become more complex. You need to maintain additional communication / "glue" code. You need to manage more dependencies. Your users will get hit by many more configuration issues. Testing becomes more difficult. It becomes harder to teach someone new about how the whole system works. You need to maintain your skills in more languages / frameworks etc.
I'd recommend the following strategy:
Pick a primary platform
Whenever you need a new library or feature, look for something on your primary platform first. Hopefully (usually?) there is something good available - but even if not then it might be worth coding something yourself if the requirement is quite small.
Only if there is no reasonable option on the primary platform, then you can start to think about integrating a new language/platform
In terms of primary platform, I'd normally suggest a JVM language like Java, Scala or Clojure since the JVM is very well engineered, offers great performance, is highly portable and has the largest / most cohesive library ecosystem (most of which is open source). The JVM is therefore probably the best "general purpose" choice unless you have some very specific requirement which is unlikely to be possible on the JVM, e.g.:
If you are doing lots of embedded / realtime / systems programming wthat requires hardware access you probably need to go for C/C++
If you are coding purely for web-based clients, you probably want to use JavaScript (if you are also writing code on the server side you can consider JavaScript code generation frameworks/libraries that can work on the JVM, e.g. Vaadin or ClojureScript)
the answer is pretty much depends on the technologies you're using and there is no silver-bullet solution for this.
In general, this solutions will fall into one of the following categories:
Some interprocess communication techniques
Integrations provided by the language/platform itself
Database/some common storage (even files :) )
Example of the first:
Sockets/pipes/whatever you operating system allows.
CORBA - allows to write distributed code in different languages.
Google protobuf - allows serialization/deserialization of data-objects and its language agnostic
For the second it really depends on language/ecosystem you're using.
Examples for java:
JNI - Java Native interface - allow to execute code (dlls/so) outside the JVM.
JCA - if you're in the enterprise environment - you can write the integration with the legacy systems in this.
For languages that are compiled into the native code its less tricky - you can write and compile some code, say in Pascal, and then use the DLL in C.
Sometimes when we're talking about Java there is a plethora of languages that have their own syntax and compiler, but their compiler compiles into java binary code that can be run inside the jvm. So if your solution is based on these languages the integration will be easier. Languages like Scala, Groovy, Closure, Jython and so on are falling into this category.
The last but not the least technology to be mentioned is Web Services. This is a very popular tool for integration of different system, although its more used in enterprise environment.
Basically its an abstraction over the sockets layer that allows to send data objects in XML/JSON format between the processes/servers. Both of XML and JSON are language agnostic, so its not an issue to create an XML in a program written in C++ and then consume it in JAVA.
Hope this helps
I am about to get involved in a NLP-related project and I need to use various libraries. Some are in java, others in C/C++ (for tasks that require more speed) and finally some are in Python. I was thinking of using Python as the "glue" and create wrapper-classes for every task that I want to do that relies on a different language. In order to do that, the wrapper class, for example, would execute the java program and communicate with it using pipes.
My questions are:
Do you think that would work for cpu-demanding and highly repetitive tasks? Or would the overhead added by the pipe-communication be too heavy?
Is there any other (preferably simple) architecture that you would suggest?
I would simply advise not doing this.
Don't implement stuff in C/C++ "for speed". The performance benefit is not likely to be as great as you expect; e.g. compared with implementing in Java using "best practice" design and performance techniques.
Don't try and glue lots of languages together. You are setting yourself up for lots of portability issues, difficulties in debugging, and reliability issues; e.g. due to C / C++ bugs crashing the JVM. In addition, there are performance overheads in bridging between languages, and there can be unexpected bottlenecks. (For instance, you may find that your C/C++ has to be run single-threaded due to threading issues, and that you therefore can't get the benefit of Java multi-threading on a typically multi-core system.)
Instead, I advise you to look for libraries that allow you to implement the entire application in one language. If that is not possible, design it so that the different language components are different executables / processes, communicating via some kind of RPC, messaging, or whatever.
Whether or not you'd have problems communicating over pipes / sockets has nothing to do with how CPU intensive the tasks are, but how frequently you'd need to send information between the processes and how much data they need to send. Setting up threads to do your communication will have little processing overhead.
You can probably automatically wrap the C/C++ code with Python (SWIG, ctypesgen, Boost.Python), so the only glue you'll have to write yourself would then be talking to Java.
You could also do it the other way -- run the Python code in the JVM with Jython so the Python and Java code are together, then talk to the C/C++ from there.
You should take a look at Apache UIMA. It is designed exactly for this. From the project website:
The Frameworks run the components, and are available for both Java and C++. The Java Framework supports running both Java and non-Java components (using the C++ framework). The C++ framework, besides supporting annotators written in C/C++, also supports Perl, Python, and TCL annotators.
UIMA can manage pipes and annotators and is built to scale.
I would look at Jepp or JPype instead of using IPC for this. I would avoid Jython since loading the C/C++ libraries into Java would probably be harder than into CPython.
1) Do you think that would work for cpu-demanding and highly repetitive tasks? Or would the overhead added by the pipe-communication be too heavy?
Depends on your task. If this is a typical NLP app where you have a large model loaded in memory and you only communicate relatively small pieces of data (strings in, label sequences/parse trees out), it may work. Pipe communication is hard to get right, though, since there's a lot of buffering and synchronization issues you have to tackle. Python is a very good glue language, but it doesn't solve everything.
2) Is there any other (preferably simple) architecture that you would suggest?
Make your NLP components services and connect to them via REST interfaces. There are off-the-shelf tools that do this, e.g. CLAM. Pyro and SPIRO make communication between Java and Python even more direct and might be easier to use than HTTP/REST (but YMMV).
The parts that are written in C/C++ can also be integrated with CPython using Cython. Don't start implementing things in C or C++ because you think they'll be faster, though; you can also implement them in Python first, then see if you can get the desired performance with NumPy and/or Cython.
Are there inexpensive or free gateways from .NET to Java? I'm looking at some data acquisition hardware which has drivers for C/C++ and .NET -- I really don't want to do any programming in .NET.
Update: I haven't done what I originally wanted to do, but I've done something similar, using JNA to encapsulate some functions from a DLL, in order to control a USB hardware device from Java. (the DLL comes from the device manufacturer) It works really nicely. Thanks!
You could also try to use JNA for accessing the native library. JNA provides Java programs easy access to native shared libraries (DLLs on Windows) without writing anything but Java codeāno JNI or native code is required. If their API is fairly straight foward, this might be the path of least resistance.
See their getting started guide where they call some native code (printf and GetSystemTime).
Well, there's JNBridge and EZ JCom, just from a Google search.
You could also use IKVM which is a slightly different approach.
(Any reason for not wanting to learn .NET, out of interest? It's a nice platform, and C# is a lovely language...)
If they have C++ versions of the drivers then you could write a wrapper around it using JNI and then load that in Java. JNI can be a bit of a pain, but it would let you use the C++ version of their drivers and not have to deal with .Net at all if you don't want.
I am partial to the recommendation to jump in the deep end with C# since it is so similar to Java. I did this and used IKVM to compile my favorite Java libs. to .NET assemblies and you get [nearly] all the core java runtime classes to boot, so if you tire of trying to find just the right C# collection type, you can always go back to java.util. (No generic collections though. Not sure why.)
Depending on what platform you're on, you have several choices for free IDEs too. For windows you can get Visual Studio Express for free but I also use SharpDevelop. You can also get the Mono IDE on Linux (and a few flavours of Unix, I think ?).
The C# learning curve is shallow if you already know Java. I only blew off 1.5 limbs on landmines that came out of nowhere for reasons I still don't understand, but workarounds were easy to come by. The worst thing about it was the darn developer docs which are AWFUL on account of being so slow. I really miss the snappiness of JavaDoc. Not only are the online docs incredibly slow, the problem is compounded by someones's iffy decision to put class summaries, constructors and methods/properties all on seperate pages so it just takes forever. Someone said to get the docs installer and install docs locally for a slightly improved experience. Not a bad idea I suppose.
I am author of jni4net, open source interprocess bridge between JVM and CLR. It's build on top of JNI and PInvoke. No C/C++ code needed. I hope it will help you.
If you have a Java application, the JNI mentioned by the others will be the way to go. You write some wrapper classes, and that's it.
If writing the wrappes is a too big task (depending on the number of methods you have to wrap), have a look at SWIG . I think it generates wrappers automatically, but I never actually used it.
If you want to code in the Java language, but you don't care if your program will run on the JRE/JVM, then you might as well use Microsoft J#. Basically, it's writing Java-Code wich is compiled to .NET-Bytecode and can use the .NET classes of the driver as well as your existing Java classes. With J# you will run into problems if your existing Java-code is newer than Java 1.4, look at this question on how to solve them.
From that point on, you could later add code in J#, C# or any other .NET language. However, you won't get back to the JRE/JVM easily.