Creating a JVM from C - java

How does one start a Java VM from C? Writing the C code seems to be straigtforward -- I've been following the code that appears on p. 84 of Liang's "The Java Native Interface". It's the linking process that has me stymied. Liang's book is 10+ years out of date in that regard and I can't find anything on the net which addresses this goal (and which works).
To be clear, what I want to do is launch a standard windows program (written in C), which then launches the JVM and calls a main() in a Java class (which I have written). This program should not rely the presence of jvm.dll or jvm.lib -- the user shouldn't have to install Java to run the program. Maybe this isn't possible without an unreasonable amount of effort.
The development environment is MinGW under windows. I'm able to link in such a way that the program works when the .dll is in a separate file, but not in a way so that there's only a single executable without any .dlls or .libs.
In hindsight, I can see now that this was a dumb question, or at least one that hadn't been thought through. The moral of the story is that the "JVM" is not a single executable, or even an executable plus some JAR files; the JVM relies on a slew of independently stored files with various mutual dependencies. Unraveling all of these relationships so that they could be brought into a single file (or even two files) would be a massive undertaking. Thanks for the knock in the head.

So, to be clear - you want to launch a JVM without the requirement of a JVM being present? How do you propose to accomplish that? Unless you're contemplating writing your own JVM implementation (which I'd say falls under the category "unreasonable amount of effort"), having a JVM installed is a reasonable requirement. Assuming that, you can just spawn a java process and include the appropriate command-line parameters (classpath, class to run etc).

Disclaimer: I don't think that having a Java runtime installed is unreasonable for users. That said, I do understand your motivations for a low-friction install for users.
Using the Sun JRE is probably not going to be fruitful here. In theory, you could grab the Sun JRE, modify it to build as a static library instead of a DLL and figure out a way to cram all the resources that get bundled with it (fonts, images, cursors, SSL certificates, localized message files, etc.) into a single resource and then modify the runtime to load from there. But this is almost certainly an "unreasonable amount of effort."
You might want to look at GCJ instead: its architecture is different than the Sun JRE which lends itself more to being embedded in another application, or it can compile your Java to native machine code.
(Also, do check the licensing to ensure that you can properly redistribute this no matter which route you take.)

Related

Is Java really that cross platform?

Nowadays, I've started hearing a lot about Java. I know that its because its meant to be cross platform. But is it really?
How much can we trust the client to have JVM installed? I've quite a few books on Java in my home and really wish to read them. But every time the same question strikes me. Will the apps which I develop with Java run on most of the machines? Isn't that bad?
One way out is to use some compilers to compile Java code to native machine code. But this makes me feel, "Why use Java then?"
So, Is it worth to learn Java for cross platform? Any ideas regarding the percentage of people having JVM installed?
I would like to correct you, People dont require jre installed they require jvm.
Since Java only relies on JVM, it is platform independent (if the platform has JVM installed).
But the main thing is, That the programmer do not have to know specific knowledge of the Platform and program his application keeping one specific platform in mind. He just has to write code generate byteCode and rest part is handled by JVM, to run it on any other platform.
If you compare java with other language you will get the exact difference like in In c/c++ the source code(c program file) after the compilation using a compiler is directly converted to native machine code(which is understandable to particular machine on which u compiling the code). And hence the compiled code of c/c++ can not run on different OS.
Nowadays, I've started hearing a lot about Java. I know that its because its meant to be cross platform. But is it really?
Yes, Java is cross-platform - or, more accurately, portable. It runs on the most used architectures and platforms, often without modification, which makes it one of the most portable languages out there. (But keep in mind that you can write unportable code in almost any language and Java is no exception.)
How much can we trust the client to have JRE installed?
We can't, but that's almost never problem.
Most languages need runtimes in order to operate. The C language (and some of its derivatives, like C++) get away with the fact that the C runtime is often already installed in the OS.
For most other languages, we trust the end user to be at least willing (not even necessarily able) to install the required runtime in order to run our (and others') software. Most software these days (and this often includes C++ software) installs its required dependencies automatically in the installation script. If this isn't desirable for any reason, an alternative is to bundle (statically link) the runtime with the program when deploying it.
One way out is to use some compilers to compile Java code to native machine code. But this makes me feel, "Why use Java then?"
Not all languages that compile to native code are the same. They have different features, different tools, different libraries available, and so on.
In any case, make sure you're not confusing native compilation with static linking of any dependencies (runtime or libraries).
Even, tell me how much percent people have a JRE installed.
About 97% of enterprise computers and 89% of desktops in the USA are estimated to run Java.
The client needs a JVM, not a JRE. They will run on almost all machines. I don't have a percentage but considering that pretty much every major OS has a JVM available to them, I would say around 95% (underestimation in my opinion). Java definitely does not have a limited audience so that shouldn't stop you from using Java.
Updated in light of Andreas' comment. I was under the impression that a lot of machines came pre-installed with Java. However, the JVM can be easily downloaded so you still don't have to worry too much about whether you're going to miss out on a large audience.
I think you mixed two different concepts:
Cross-platform: A program is considered to be cross-platform if it can run on different platforms without a need to recompile it.
Q: Is Java cross-platform?
A: Of course it is.
Native app: A program that runs on the targeted platform without a need to install, download any other software. Usually the program is compiled into a machine binary. However, it may in some definitions include programs/scripts that are not machine binaries, but the target it platform is guaranteed to run them with its built-in library/software.
Q: Can Java run on any platform without JVM?
A: No. JVM is not shipped with any platform that I'm aware of, so it needs to be downloaded and installed before any Java program can run.
One way out is to use some compilers to compile Java code to native machine code. But this makes me feel, "Why use Java then?"
It all depends on what you want to achieve. If you want to create native apps, drivers, etc, then Java is definitely the wrong tool. But if you want to create an app that can run on all platform without having to recompile it and create a version for each platform, then Java can be a good option.
So, Is it worth to learn Java for cross platform? Any ideas regarding the percentage of people having JVM installed?
Again, it really depends on what you want to achieve. Java is a good option for creating cross-platform apps and it is worth learning. However, there are other options that you may want to look into, compare, and decide which one to learn. C# is a great language, and just recently, Microsoft announced its plans to make it truly cross-platform, so it is another good option.
Most PCs have JVM installed. Theodoros Chatzigiannakis provided some statistics in his answer. But you shouldn't be too worried about the numbers. Those few who don't have JVM installed, will be willing to download and install it if they like your app.
Note: In the past, you could run apps written in C# on platforms other than Windows, but you needed a .Net Framework equivalent (e.g. Mono). With Microsoft recent announcement, we should be able to use Microsoft .Net Framework itself on other platforms. We will see how this will turn out.

Diference between jdk/bin/java and jdk/jre/bin/java

Making somes tests this week i found this situation:
When i run the tomcat using the java executable in jdk/jre/bin/java the performance is a lot betther than when i run with jdk/bin/java.
The question is: Someone knows why the jdk package delivers 2 java executables and what is the difference between them that justifies the performance difference?
I'm late to the party, but... I came here looking for the difference between the several java variants within OpenJDK. I only ended up with a few clarifications and additional questions to the "what's the difference between them" part of the question; hope it's helpful.
Looking inside the OpenJDK (I'm using OpenJDK 1.7.0) base directory I see three javas, all with different hash-sums:
bin/java, binary
jre-abrt/bin/java, binary; assuming ABRT is Automatic Bug Reporting Tool
jre/bin/java, a shell script that execs the jre-abrt/bin/java variant, in one of two different ways (more below).
The binary variants above have the same file-size and creation-time (in my version and system, anyway) but 4 bytes differ between the two files (I haven't looked much further -- this is the other part of your question -- but they are different, and it doesn't look like an ASCII string, for instance).
The script variant is the one you're saying is faster, which seems counterintuitive because it seems to be doing more. (Or perhaps you're only seeing the time to execute the script and not the exec'd java command?). The script checks to see if an ABRT shared-object file exists, and if so it passes (as -agentpath...) the .so and abrt=on. Again, this seems like it should be nothing but more work... assuming use of ABRT.
If you're still interested in this topic, perhaps it would be interesting to see the following:
what path in that script you're taking (check for existence of /usr/lib64/libabrt-java-connector.so or whatever is in your jre/bin/java script)
if directly executing the third variant (jre-abrt/bin/java) is faster
what else is being touched in both of these cases -- like inotify or strace or something, but this is probably enormous for a service like this.
the java.exe files are actually the same. The JDK is the Java Development Kit, which includes all of the java executables you need to develop applications.
The JRE is the Java Runtime Environment, which includes what you need to run Java applications
So for running the application in a deployed mode, you would need only the JRE, as end users are likely to have only a JRE and not a JDK.

How does Java differ on different platforms?

I am currently in high school. I was recently browsing the internet looking for what employees in the software industry usually want and what the job requirements are like.
I came accros a job description and one of the requirement is:
Strong, object-oriented design and coding skills (C/C++ and/or Java
preferably on a UNIX or Linux platform)
Note the last part: Java preferably on a UNIX or Linux platform.
I don't understand this. Isn't Java run inside a virtual environment/machine? Why would it matter what OS it is running on since Java cannot directly interact with the OS?
A developer job description may require experience with some OS for several reasons:
First, as you noticed already, there are languages that talk directly to the OS and the code needs to be aware of the underlying OS (like C/C++, which are listed in your job description).
Secondly, even if the programming language abstracts away anything that's OS-specific from you (including the file-system / path separators), you are still going to deploy / configure / run / monitor your applications on top of some OS and you need to know (at least) the basics in order to do that.
For a Java job description, If UNIX/Linux "is a plus", it usually means you're going to run your code on a UNIX/Linux system and you should know how to start a process (your own java app or some application server), how to deploy an application in a container, how to read log files and so on...
While Java the language runs on a virtual machine, the Java library must abstract access to facilities available on the host platform. Ideally, these abstractions are cross-platform, but the devil is in the details—hence the preference for experience on a particular target platform.
Develop once debug everywhere
While conceptually it shouldn't make any difference on what target platform the java code is executed on unfortunately in practice it isn't always that simple but a rather tedious task to get the code running on any platform.
Beginning from easy to circumvent mistakes e.g. using / or \ instead of java.io.File.separatorChar or : / ; instead of or java.io.File.pathSeparatorChar
there are most often problems including methods implemented in native code that often aren't that compatible across different platforms.
It might be even possible your employer is looking for someone to implement native java methods using JNI.
First, you're right in that Java runs inside of a virtual machine - it doesn't directly expose the inner workings of the system to you. However, that doesn't mean that each system doesn't differ in some way under the covers - different flavors of operating systems have different kernels, different ways they think about scheduling, different ways to handle threading, and different interrupt chains (Linux has quite a few signals, whereas Windows has a handful).
As far as Java (the language) is concerned, it runs the same everywhere. How it's actually accomplished is dependent on the native JVM that it's running on.
For this job posting, though, I wouldn't read too much into the UNIX/Linux portion. This is more or less gauging how comfortable someone would be working in a UNIX or Linux environment while programming Java. The majority of IDEs available for Java are cross-platform, but that shop may be using Mac or some flavor of *nix (RHEL, Debian, Ubuntu, etc). It'd also be important to make use of the command line/shell script, since a lot of the convenience of working with UNIX/Linux is on the command line.
Not every shop uses Windows machines to develop on. Just a heads-up.
Java does not differ on different platforms. That is the most highlighting feature of Java ( portability ). The JVM abstracts the underlying platform.
However, platform matters when it comes to a software development, which involves not just the coding part. Mostly in industries, devs work on Linux platform by logging into a terminal. You don't get a GUI as in Windows and a good IDE like NetBeans. So in that case, you should know how to compile and run a java program from terminal.
Example, In linux, In order to create a package, you create a directory ( folder ), say myJava/. You go into it (cd myJava) and write the SomeThing.java file and compile using javac SomeThing.java and you get a SomeThing.class file ( inside myJava ). Now in order to execute this, you need to use the java command. Prior using it, you need to move to the parent directory containing this package. Then execute as java myJava.SomeThing. You wouldn't be knowing this unless you play around in Linux platform. Other things like setting up the classpath etc are also matters of concern

Java to EXE good or bad idea?

I have been wondering for a long time about converting Java projects to EXE.
The advantages relies in the faster deployment on Windows where the user simply double clicks the EXE and the application is launched where is with Java, he has to run certain commands.
But EXE is really not what the Java was intended for which is portability.
So what do you think, Java to EXE good or bad idea?
I found some interesting article here.
Update
Wow, so may contradicting views so far. I would like you guys to add the pros and cons of the JAVA to EXE.
Since my expertise is with Java Web Start, which is for launching desktop apps. with a GUI, please consider my advice to be targeted mostly at those types of apps.
Other people have commented on the OS specific nature of an EXE. I always have to wonder why people choose Java to develop Windows specific desktop apps., since the Visual Studio software for Windows would probably make both GUI development (no x-plat Java layouts to bend your head around) and deployment (just guessing it can produce an EXE) easier.
OTOH only you can say what is the best development tool/language for this use-case.
As to the potential disadvantages of creating an EXE, I note at the JavaFAQ on EXEs.
There are a number of good reasons not to package your application in an executable. Daniel Sjöblom notes:
It will probably not be any faster. Modern virtual machines don't interpret bytecodes, they actually employ a JIT compiler to produce native, compiled code. Check Sun's site for further information on JIT compilers.
Static compilation increases the size of your application multifold, since all of the libraries you are using need to be linked into the application.
You lose 'free' upgrades to your program. Anytime your user downloads a new faster virtual machine, your app gets a speed boost. If you are using an exe, you will not get this benefit.
Jon A. Cruz details some of the extra steps in the development process required to create an exe. He points out that developers making native exe's need to:
Validate the latest versions of the compilation product from the vendor. If critical bugs are found, it can't be used to build a shipping product until those are addressed. Work that needs to be done each time a revision comes out from the vendor.
Submit the software through a QA cycle. Once engineering thinks things are done, they need to be verified. So every shipping version and update of a product needs to go through complete testing cycles.
Further, since native compilation is per target platform, the QA cycle needs to be done completely for each target platform, which multiplies effort required.
Shelf space. Maybe not a big deal nowadays, but could be.
Then one needs to get all customers to upgrade to the proper version. Either have free updates (in which case the business needs to absorb the cost of producing updates) or alternatively needs to handle clients not all updating.
Jon notes futher: When you ship standard Java bytecodes, VM problems are the responsibility of the platform or VM vendor. However, when you ship compiled binaries, they become your responsibility (even if they're actually bugs in the vendor's compilation product).
...
Of course, my first choice for deploying Java rich client apps. is using Java Web Start. Putting some of the benefits/features of web-start in point form:
JWS provides many appealing features including, but not limited to:
splash screens
desktop integration
file associations
automatic update (including lazy downloads and programmatic control of updates)
partitioning of natives & other resource downloads by platform, architecture or Java version,
configuration of run-time environment (minimum J2SE version, run-time options, RAM etc.)
easy management of common resources using extensions
..
I decided to highlight auto-update since with the gradual shift from apps. delivered on disk to apps. delivered over a network, auto-update is becoming more common. JWS still provides the best update experience (very configurable, mostly transparent to the user) I've seen.
And of course, JWS works on OS' for desktop PCs for which Java is available.
Update
..does Java web apps require internet connection?
(Note that name is 'Java Web Start'.)
Sure it does. At least for the initial installation. Update checks can be specified to continue to launch the previously installed version of the app. if the user is not currently connected.
But then, (in my estimation) there are more machines (such as Netbooks) with no CD/DVD drive, than there are without internet connections. If you want to sell to the larger market, look to the network to deliver the app.
It depends on your needs. We had written a little barcode client scanner app here for our customer. They run it on two Windows-PCs. They are happy having their well-known exe-files. We coded it in Java and created an EXE-file for them.
Both parties are happy with it - so why not doing it?
When there are good reasons for it and nothing against it except dogmatism then it is ok in my opinion.
I am the author of the article you linked to - glad you've found it interesting!
As my article states, and as others have already pointed out in their answers, there are multiple ways to simplify deployment of Java apps - JNLP, EXE wrappers, installers bundling a private JRE, and so on. But true native compilation is the only option that also provides protection against Java decompilers - you simply do not ship the bytecodes.
Of course, that does not make reverse engineering of and tampering with your code impossible, just much more costly in terms of required skillset and time.
As far as application performance is concerned, native compilation can make a big difference if you target embedded systems. This also applies to memory and disk footprint, albeit to a smaller extent. On the desktop you would typically get better startup, but in most other scenarios and aspects the results would depend on your app.
If it has a good reason why not? Even Eclipse has an EXE on windows and (and platform dependent binaries for linux, mac, etc) Of course you loose portability but if that is not important then go ahead.
UPDATE
The question is what do you want to achieve by creating an exe :
Convenience : users on windows prefer to click on icons, this is especially true for the non geeks. On the other hand non geeks don't care what the link does internally if it starts up an exe or something else. You can have an application icon for non native Java applications too. The alternatives would be
Web start
Creating an installer package,e.g.: http://www.advancedinstaller.com/java.html This can also solve the problem of installing the JRE
Performance : If you compile your Java application into a native solution you may gain a bit on performance but it depends on what technology you use. For example Swing tends to be slow but compiling that to native is rather tricky. If you use SWT instead of Swing that is already using native components therefore no need for further native compilation. On the other hand recent JVMs perform very well and can compile java to native to further improve the performance bottlenecks. This is done silently on the background you dont need to worry about that.
Sum : in some cases it might be the only solution, but if you choose the right technologies there will be many Java based alternative solutions to reach the same goal.
The page behind the link in the question is written by a company that sells products that compile java to native code. I would not base a decision on that alone.
The question also says that the advantage of the exe a better user experience, because the user can just double click to launch the application.
That is possible with executable jar file. In fact, its actually quite easy with standard tools in the java runtime. You just have to add a manifest to a jar file, and specify the class with the main in it. You can also specify other jar files in the classpath relative to the location of the main jar file. You can also specify an image to use as a splash screen as a resource.
e.g.
Class-Path: lib/derby.jar lib/derbytools.jar lib/jcalendar-1.3.2.jar l
ib/joda-time-1.4.jar lib/log4j-1.2.14.jar lib/looks-2.2.1.jar lib/swi
ng-layout-1.0.jar
SplashScreen-Image: resources/splash.png
Main-Class: com.you.pkg.app.Main
The basic ant project in Netbeans will do all but the spash-screen for you if you use it. If your some reason you want to do all of that by hand, make sure you understand the format of the manifest file, its a bit finicky.
As Linux, mac., Solaris user I think this is bad idea.
If you want faster deploy on windows, just create installer.
Jar files provide many benefits including:
Compact: The whole application (i.e. all the class files) is stored in one archive file (which can incorporate image and sound files if required).
Ease of use: The application can be run by double-clicking.
Compression: The jar format allows you to compress your files for efficient storage.
Security: You can digitally sign the contents of a jar file. Users who recognise your signature can then optionally grant your software security privileges it wouldn't otherwise have.
I would not convert to exe.
Most Windows applications run from a .exe file (Word, Internet Explorer, FireFox, NetBeans, ...)
Java itself has no support for doing this as the executable file will then be platform dependent (i.e. it won’t run on Macs)
However, there are (free) applications that can do this for you.
Minecraft does it, so it must be a good idea!
All jokes aside, understand that it's not 'conversion' that you are looking for, but using a custom launcher. The article you linked does a nice job of explaining the different approaches and pros/cons of each. As a general idea, it requires the extra work of creating the launcher (and a different version for each different OS architecture), but it gives you a little more control (version checking is a nice feature, also you may update the application jar rather easily, like Minecraft does). Overall it's a good idea if you think it's worth the effort, and the (little) loss in portability.
Edit: the 'Custom Java Launchers And Wrappers' approach is the one that you should use if you don't need the really nifty extra features offered by those below it.
Depends on the user base. If they are tech-related in anyway then giving them a .jar file (which could be run by double click) is a good idea for mobility.
If your users are less techy but you still need it to run on multiple platforms then wrap it as exe for Windows and as .app for Mac.
Important: I would suggest making a script to wrap it into exe, so you run it each time you have a new version.

building a system in Java and assembly language that runs on "bare metal"

Alright everyone,
Let's say i wanted to make a system that used only assembly and java, my question would be, as long as i included all of the jvm folders, classes, jars, etc.. java should still function effectively?
i understand there are those things that are compiled platform specifically but this is why i am asking, is it possible, using assembly to replicate all of the .exe, or other executable files that java has included into a pure assembly/java system?
If you are asking whether it is possible to build a system in Java and assembly language that runs on "bare metal", the answer is yes. There are a couple of current examples:
JavaOS is targeted primarily at the embedded systems domain. (Sun consider SunOS to be a "legacy" product line these days.)
JNode aims are broader, and encompass embedded systems, desktop systems, servers and cloud computing.
Be aware that building a system of this kind is a multi-year, multi-person project requiring deep understanding of virtual machine internals, compilers, garbage collectors, hardware architectures, device driver writing and so on.
If you are asking about something else, please be more explicit.
EDIT: responding to the OP's followup question:
It is not practical to use the Java and other "exe" files per se. They require a fully fledged operating system underneath them; e.g. Windows, Linux, whatever. If you had access to the source code, you could conceivably rewrite as required to make them run on "bare metal", but that would entail significant architectural changes, especially if you want to write device drivers, etc in Java. (Besides, the core of Sun's JRE is implemented in C++ ... ).
You cannot directly use the existing Java class library JAR files, because they include a significant amount of platform specific code. However, you can build your own Java class library JARs from an existing open-source version of the Java class libraries (e.g. the OpenJDK 6.0 J2SE libraries). You deal with the platform specific code by providing your own versions as native libraries or (as JNode does) as Java classes.
If I understand your question correctly, you mean something like JavaOS. Sure, its possible to implement the JVM raw on the hardware, not sure why you would, though. And if you did, why you wouldn't use C instead of Assembly for most of the work.
Its theoretically possible to implement the jvm in a whole other language. The best example I can think of is Python/Jpython where there is the original C implementation and a pure Java implementation of the language.
The main argumant against this is -- its a ton of work for not much benefit.
The official Sun jvm and supporting jni libraries are written mostly in C, you would need to provide native assembler implementations for most of the C POSIX APIs at the very least.
Also the original design goal of C was 'a portable assembly language' and to a large extent it still meets these goals. C produces efficient machine code and most C compilers will let code machine instructions inline with the C code.
Another benefit of C is the number of cross compilers available, you dont need to run the development environment on tHe target architecture, you can deveop and unit test on your favourite paltform/IDE, when you are ready you can then export your executables to the target platform.
Jikes RVM and Sun's Maxine provide a JVM implementation with little (of the order of 1 kloc) native code. However, both VMs require an OS and are only research implementations. The process of creating a stream of octets that form machine code, is obviously achievable in Java.
Have a look at JNode. They have been working on this for years.
http://www.jnode.org/

Categories

Resources