Java only Operating System - java

Are there any operating systems that when fully loaded only provide a java environment for console application execution? Ideally one which will automatically start programs when its loaded up

Here is a such thing with name: JavaOS
From my point of view better approach is to install a Linux distribution pack or small Linux distribution pack with java support and put your java code to the OS startup. To run it when OS has been started.

There's also the Phantom OS, being worked on by some Russian programmers. The system has no concept of files. Everything is an object living in one large memory space.

Even if it did exist, it would not by itself provide any security benefits.
A java application can still exercise almost all user-ring authority made available by the OS. If it can write somewhere on the library load path or start another java application with a specified library load path then it can:
Write out a native library to the file-system.
Define a class with native methods backed by that library.
Call System.loadLibrary to load that library.
Invoke those native method to execute arbitrary user-ring code.
If you want an operating system that allows you to effectively control the authority available via the shell, then read up on
"secure operating systems" like KeyKOS,
sandboxing processes using "virtual machines", and
providing a smaller shell interface using "restricted shells".

Related

How can dynamic JVM command line flags be passed to a self-contained JavaFX application?

EDIT: Oracle accept my bug report requesting an enhancement as JDK-8138944 : Support command line arguments to the JVM passed to self-contained app launchers.
The problem
My team is working on an open source Java SE project, ImageJ, that currently has a custom native launcher written in cross-platform C. We would like to move away from this launcher, switching to a more modern, industry standard and maintainable deployment mechanism. JavaFX self-contained applications are the most promising solution we have found so far.
One great feature of ImageJ's current native launcher is its ability to customize how the JVM is launched. For example, you can write:
ImageJ --debugger=8000 myFile.png
And the launcher will invoke the JVM with flag:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=localhost:8000
while keeping the myFile.png as an argument to the Java main class.
But from the docs, we cannot see a way to accomplish something similar with the JavaFX packaging tool.
Considerations
I know that the UserJvmOptionsService provides a means to configure how the JVM is started (via Java Preferences API internally, which the JavaFX launcher reads before JVM startup). This is nice for providing the user with a friendly dialog box where they can tweak maximum heap size and other common parameters. Certainly we could add a remote debugging toggle and port settings to such a dialog box, and/or support JVM configuration via the CLI—but it would then require a restart of the application.
Ideally we would not need to support this scenario at all, and instead would handle all command line arguments after the JVM starts up, in Java. For example, in most cases, system properties of the form -Dfoo=bar can be supported by simply parsing the arg and setting the system property at runtime, as long as it is done early enough in the application's startup cycle. But there are clearly many cases where doing it after JVM startup is too late:
The debugging example above (you can't enable remote debugging after startup).
Heap size tuning
Garbage collection tuning
Verbose class loading (-verbose)
Interpreted mode (-Xint)
Lots of other examples
Our users expect to be able to pass these settings on the CLI, and have the Java runtime operate accordingly—and in the case of ImageJ, it is particularly important for backward compatibility.
Possible solutions
We could retain the native C launcher, replacing the native executable that the Java packaging tool installs. But this strikes me as highly fragile, and largely defeats the purpose of switching to JavaFX deployment, since we would still need to maintain, build and test the custom native launcher across several different platforms.
Alternately, we could have the application main class be a very thin CLI option parser, which then spawns a second instance of the JVM. This would keep the bootstrapping logic in pure Java, which would be far more maintainable than the current native C code, while fully leveraging the JavaFX deployment scheme's cross-platform bundling capabilities. But that seems like a big hack with potentially challenging side effects.
Finally, the question
Has anyone achieved support for JVM CLI arguments with JavaFX self-contained application deployment? If so, how did you accomplish it? If not, any alternative suggestions?
You can modify the launch arguments to the JVM by modifying the jvm user overrides config file that the API writes to:
• Mac ~/Library/Application Support/[app.preferences.id]/packager/jvmuserargs.cfg
• Windows C:\Users[username]\AppData\Roaming[app.preferences.id]\packager\jvmuserargs.cfg
• Linux ~/.local/[app.preferences.id]/packager/jvmuserargs.cfg
NOTE: This is an internal implementation detail and subject to change.
Rather than having any kind of two-phase launch system, where you see what options you have and then launch a replacement JVM, I would suggest you create your own native launcher by copying and editing the platform java.c launcher. You can see what they are doing in the open JDK project.
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/914cd9b482c8/src/share/bin/java.c
There are quite a few places where they are looking for various options and converting them into init arguments for the JVM itself. Take a look at the functions ParseArguments, AddApplicationOptions, TranslateApplicationArgs, CheckJvmType, AddOption etc.
I am no C programmer but I have maintained my own launcher on quite a few occasions: such as a launcher that loaded a specific class path from a one-entry-per-line text file that could be checked into source control and one that used a different entry point to main(). It doesn't change that much and you can isolate your changes quite easily, so that they are easy to reapply on later versions of java.c. For your purposes, you would not really need to change every time someone makes a change to java.c, you only really need to change it when JavaVMInitArgs or some other critical aspect of the invocation interface changes.
I am sure that if you proposed and contributed a more elegant option-handling solution, maybe one that behaved differently when argv[0] is not 'java', then maybe the open jdk team would adopt your approach and maintain it for you, or for all us. I am sure there are lots of developers out there needing features like these.

Limit resource utilization of JNA calls without changing dll

How can you prevent a JNA method-call from exceeding thresholds for CPU utilization, thread-counts, and memory limits?
Background:
I'm working on a safety critical application and one of the non-safety-critical features requires the use of a library written in C. The dlls have been given to me as a black-box and there's no chance that I'll get access to the source code beyond the java interface files. Is there a way to limit the CPU usage, thread-count, and memory used by the JNA code?
See ulimit and sysctl, which are applicable to your overall JVM process (or any other process, for that matter).
It's not readily possible to segment parts of your JVM which are making native accesses via JNA from those that aren't, though.
You should run some profiling while you exercise your shared library to figure out what resources it does use, so you can focus on setting limits around those (lsof or strace would be used on linux, I'm not sure of the equivalent on windows).
For most operating systems you must either call your C code from a new thread or new process. I would recommend calling it from a new process as then you can sandbox it easier and deeper. Typically on a Unix like system one switches to a new user set aside for the service and that has user resource limits on it. However, on Linux one can use user namespaces and cgroups for more dynamic and flexible sandboxing. On Microsoft Windows one typically uses Job objects for resource sandboxing but permissions based sandboxing is more complicated (a lot of Windows is easily sandboxable with access controls but the GUI and window messaging parts make things complicated and annoying).

Can multiple JVM processes share memory for common classes?

I'd like to run multiple Java processes on my web server, one for each web app. I'm using a web framework (Play) that has a lot of supporting classes and jar files, and the Java processes use a lot of memory. One Play process shows about 225MB of "resident private" memory. (I'm testing this on Mac OS X, with Java 1.7.0_05.) The app-specific code might only be a few MB. I know that typical Java web apps are jars added to one server process (Tomcat, etc), but it appears the standard way to run Play is as a standalone app/process. If these were C programs, most of that 200MB would be shared library and not duplicated in each app. Is there a way to make this happen in Java? I see some pages about class data sharing, but that appears to apply only to the core runtime classes.
At this time and with the Oracle VM, this isn't possible.
But I agree, it would be a nice feature, especially since Java has all the information it needs to do that automatically.
Of the top of my hat, I think that the JIT is the only reason why this can't work: The JIT takes runtime behavior into account. So if app A uses some code in a different pattern than app B, that would result in different assembler code generated at runtime.
But then, the usual "pattern" is "how often is this code used." So if app A called some method very often and B didn't, they could still share the code because A has already paid the price for optimizing/compiling it.
What you can try is deploy several applications as WAR files into a single VM. But from my experience, that often causes problems with code that doesn't correctly clean up thread locals or shutdown hooks.
IBM JDK has a jvm parameter to achieve this. Check out # http://www.ibm.com/developerworks/library/j-sharedclasses/
And this takes it to the next step : http://www.ibm.com/developerworks/library/j-multitenant-java/index.html
If you're using a servlet container with virtual hosts support (I believe Tomcat does it) you would be able to use the play2-war-plugin. From Play 2.1 the requirement of always being the root app is going to be lifted so you will probably be able to use any servlet container.
One thing to keep in mind if that you will probably have to tweak the war file to move stuff from WEB-INF/lib to your servlet container's lib directory to avoid loading all the classes again and this could affect your app if it uses singleton or other forms of class shared data.
The problem of sharing memory between JVM instances is more pressing on mobile platforms, and as far as I know Android has a pretty clever solution for that in Zygote: the VM is initialized and then when running the app it is fork()ed. Linux uses copy-on-write on the RAM pages, so most of the data won't be duplicated.
Porting this solution might be possible, if you're running on Linux and want to try using Dalvik as your VM (I saw claims that there is a working port of tomcat on Dalvik). I would expect this to be a huge amount of work, eventually saving you few $s on memory upgrades.

Why is Java platform independent in theory and platform dependent in practice?

I know that one of the big things about Java is that it is platform independent in the sense that you can make a Java application and have it run in Windows, Linux, Mac, and so forth, as long as you don't use libraries specific to one OS, and as long as you have a JVM installed for the appropriate OS to interpret things correctly...
However, why can't a normal computer Java program (as in a simple Hello World in Java, for Windows or Linux for example) run just the same in a mobile phone, when mobile phones also have their specific JVM installed to interpret things correctly?
Why is it necessary to change the architecture of the program in some cases, such as Android development, or use Java ME to make applications specific for some general mobile phones?
I know that there are some functions that are related to certain functionalities of the OS, that might not apply in the mobile platforms for example, such as some things related with console, input methods, and so forth, but is this really the only reason that makes things not compatible? If so, why won't a simple application that just declares and initializes an integer variable be able to run across all non-mobile and mobile platforms that have a JVM available?
I am aware of other questions that have been posted before, such as this, but that do not focus the exact point I am aiming for here.
The unit of portability to look at is a class rather than an application. A class that declares and initialises an integer variable will run on all the platforms you describe, and many others too. They understand the same bytecode, even if they do execute it using different mechanisms ranging from bytecode interpreters, to JIT compilation, to Android's Dalvik (which translates JVM bytecode into its own instruction set).
Even if we look beyond a single integer variable, Java that uses "core" functionality will work on most of these devices. There's a great deal of common ground between J2ME, Android and J2SE (and particularly the latter two - J2ME was intended as a cut-down version of the standard Java APIs for devices with limited resources, so less of the standard API is available).
On a Windows/Mac/Linux system, an application is usually something that you explicitly start, use, and - when you're done - tell it to exit. Compare this with, say, an Android phone: the application might be started in response to an event occurring (perhaps an incoming SMS, or a specific type of file downloaded from the web) in which case it needs to know how and why it was started - a simple public static main(String[] args) just doesn't cut it. Once started, the app needs to be aware of events such as "low battery" or "entering standby mode" in order to free up resources or disable CPU-intensive features (such as GPS) that might otherwise drain the battery.
These aren't obscure functions - they're essential to a phone being useful as a phone - so all native applications must handle them.
When Java Code is compiled a byte code(class file) is generated which is independent of the system. This byte code is fed to the JVM (Java Virtual Machine) which resides in the system. Since every system has its own JVM, it doesn't matter where you compile the source code. The byte code generated by the compiler can be interpreted by any JVM of any machine. Hence it is called Platform independent Language.
thanks
Why is Java platform independent in theory and platform dependent in practice?
Remember and clear one thing that only the Java language is platform independent and try to understand the meaning of the sentence. Java is platform independent means the code you have developed using Java can be run on any machine.
When you compile the .java file it generates .class file and it contains bytecode and this bytecode is platform independent you can run it on any machine this is what about platform independency of Java language.
Now you said that it is not in practice so the reason is only Java language is platform independent, but its runtime enviroment, or JVM, is platform dependent, it is written separately for each OS. So we can say the Java language is platform independent, but its runtime environment is platform dependent.
The java language is just one thing but then many other devices such as mobile phones run their own version which is usually a trimmed down version to fit on the device. THese can also occasionally have other proprietary classes to help access the hardware (ie touchscreen). By making separate platforms based off a main one you get much support and a tighter more efficient programming language.
Sun micro systems has released different versions of jdk. one for windows based and another for linux/unix based. When we installed jdk with that we get jvm,jre and javac. Suppose if we write a java program in windows with intel processor which is installed with windows jdk, then the java compiler of that jdk will convert .java file to .class file which contains byte code instructions similar to assembly language code these byte code instructions can be understandable only by jvm. If we take the .class file which is generated in windows o.s and if we run in linux then the jvm of that linux machine internally rewrites your java program by using the approximate 200+ instruction sets which are developed by javasoft people and placed as part of jvm. and the .class file gets executed. So here the point is to concentrate that jdk is platform dependent but .class is not platform dependent it is platform independent because jvm only responsible for running any .class files. Every jdk's jvm internally has predefined instructions sets i.e., approx. 200+.

Restrict native code functionality from Java

I have a java application which uses JNI in some parts to do some work. It follows the usual loading of DLL and then calling native methods of DLL. Is there any way we can restrict what native methods can do from the java application? For example, can we restrict DLLs not to open any files or not to open any sockets even if it has the code to do it? It can just forbid DLLs it loads for doing certain things, may be by loggin something or throwing an exception.
No you can't. The DLL gets loaded as a whole and then the Java side has no control on what the native code is doing.
One solution might be kind of man in the middle approach. This would involve coding a "shell" DLL that has the same interface as the original DLL. You tell Java to load a "shell" DLL for instance by putting it in a specific location and using the java.library.path property. Then the role of the "shell" DLL is to load the "true" DLL by sandboxing it and redirecting standard functions. This sounds like a lot of pain and this something that would happen in the native side on things, not from Java.
Edit 2021: today it's also relevant to point out that the sandbox to run Java in would likely be a virtual machine, in the cloud, Docker or what have you, in a locked down configuration.
I liked Gregory Pakosz' answer a lot. However, what you could do is sandbox the Java instance itself. Start the Java application itself in a restricted context.
In Windows or Unix you can create a user which is limited to a certain directory and only has access to some DLLs. Thus the DLL called from JNI can do whatever it wants, but it will not get very far, because the user the Java runs as can not do very much.
If your Java program needs to do privileged things, the Java side of it will have to talk to another program (Java or not) to do its' privileged things for it.
Just keep in mind, that if you can not trust the DLL, you can no longer trust the Java code either, since the DLL might have "hacked" the Java machine. On the other hand, no nasty stuff should be able to break out of the limits of the user they run as. (Barring misconfiguration or a bug in the OS.)
Normally you would run your application under the Java security Manager but I don't believe it has any effect on code running through the JNI.
You could implement some kind of setting that your JNI code could get. For example, on an UNIX system, you could create groups for special types of privileges, and check if the current user has the required privileges, else just return 0 or something.

Categories