Packaging with a smaller JRE - java

I want to ship an open source Java project with its own JRE so that it doesn't depend on whether one is installed or not.I will have everything in one directory and my program will be the sole user of that jvm and class library.
As Java is now open source, I think I can now legally strip down the class library (rt.jar) to only classes I need. For example I don't use any SQL so I don't want to burden the download with classes in the java.SQL package.
This would be somewhat analogous to a linking step when an executable is built from libraries using only methods in the call tree that starts with the programs main().
Does anyone know what tools I might use to do that. Is it possible?

I think this is pretty much already done in Java 6 update 10.
It was planned for Java 7 but it shipped before.
It is the Java Kernel here are the details, I'm not quite sure if is what you need.
Here are the links:
http://tech.puredanger.com/java7/#kernel
http://weblogs.java.net/blog/chet/archive/2007/05/consumer_jre_le.html#JavaKernel
Here is other:
http://java.sun.com/javase/6/6u10faq.jsp#JKernel

There is a commercial tool that can legally strip down the Java class library.

Related

running java code form terminal getting error

I found some reference that says I can add #!/usr/bin/java --source 12 at the beginning of the file and run the file directly from the terminal.
I am able to run using this on my local machine, however, when I tried the same on Github action I'm getting the error error: invalid value for --source option: 12
I'm not really an expert in shell scripting or java, can someone help me understand what this --source means is it the java version, I tried setting up the same version (jdk18) on Github action but still did not work.
java (the runtime executable) can only run class files. Until, that is, java12, where a normal JDK distribution (and not the bizarro JREs that some packagers like Azul publish ^1) has a java.exe that can run java files straight up. It's simple sugar - the compiler is still involved, of course. It's just that java will execute it for you.
You don't need --source 12; just java MySourceFile.java is fine. Edit that comment at the top of your source file, it should just be #!/usr/bin/java. The thing you do need is that java on your command line PATH is a java v12 or higher, and it is not. There isn't anything your java source file can do about this, you're going to have to impose on your users to have at least java12 installed or this simply does not and can not be made to work. It looks like you're on some linux distro or other; apt or yum or snap or whatever package manager you have will tell you how to fix this: Install java17, and uninstall the rest or use java-alternatives or whatever mechanism your package manager has to set the default executable (the one /usr/bin/java links to). Read the documentation of the package supplying java17, possibly following some links to the generalized java infrastructure package, it should tell you.
Mostly this is a red herring, this just isn't how java files are distributed. It's virtually pointless because:
Java is not a language that tends to be used for quick shell script-esque things. Such things tend to be self-fulfilling prophecies: Because nobody does this, library authors aren't thinking about it when they develop their APIs and the users of their libraries won't file enhancement requests for this either. Because common libraries aren't convenient when used for quick off-the-cuff shell scripts, java isn't used for it, thus perpetuating the cycle.
Any serious java app would definitely involve packages, dependencies, and more - and such apps cannot be run like this.
Class files are as platform agnostic as source files are. There is no sane reason to distribute java-written shell-script-esque tooling as a source file instead of a jar, except for off-the-cuff editing off them, which gets you right back to point #1 and #4.
The java core APIs work on a model of lowest common denominator: If there is a major OS that cannot or doesn't work in a certain way, then java simply does not expose this at all. For example, on all posix systems (i.e. pretty much every major OS except windows), you have your usual TERM, KILL, HUP, etc signals. Java core libs don't let you interact with them (unless you dip into hidden sun.misc.* API which doesn't reliably work in the first place). This makes java extra unsuitable for quick command line scripting where you want a different model: If at least one OS can do it, the language should have a library for it, and that library should simply fast-crash if you attempt to use it on an OS that doesn't support it. One easy way around this is a third party library that adds support for OS-specific stuff, but your model of distribution (stick #!/usr/bin/java at the top and distribute a source file) cannot include dependencies.
Java as a runtime model is mostly focused on running things eventually very quickly, at the cost of starting off slowly. This is fantastic for web servers which need to run efficiently but will be running for quite some time. It's utterly unsuitable for shell scripting, though.
CONCLUSION: You don't want to stick #!/usr/bin/java at the top even if you could make it work.
[1] A JRE is a java distribution without compilers and other development tools like jstack. These cannot run java SomeSourceFile.java, obviously; they do not have a compiler. However, JREs died - there are no JREs anymore; JDK8 is the last one that shipped with an official JRE. The JRE serves as a distribution model: The end user installs a JRE, and you ship your jars to them. This model is obsolete (you are now responsible to get something that can run your class files on the deployment machine), and therefore JREs died. However, some packagers of OpenJDK builds, such as Azul, still publish them, confusing matters. Hence, 'bizarro'. Azul and co have relatively good reasons for doing it, but, you shouldn't be using these unless you really know what you are doing.

Where are the sources of sun.reflect?

While debugging Java code that uses reflection in Eclipse, some times I need to step into my invoked method or constructor. But reflection classes such as java.lang.reflect.Method and java.lang.Class do internal calls to sun.reflect.DelegatingConstructorAccessorImpl, sun.reflect.NativeConstructorAccessorImpl, sun.reflect.ReflectionFactory and others. These classes are not in the src.zip that is shipped with JDK.
This requires me to add sun.reflect.* to the debugger Step Filters. Otherwise I would have to press F5 (Step Into) multiple times in bytecode view, without any clue of when it will get into my code.
But being a curious person, I wish to know what's going on. Someone please can tell from where can I download those sources, if such a link or repository exists?
from Oracle:
Java SE 6 JDK Source Code
JDK 6 source code is available for those interested in exploring the details of the JDK. This includes schools, universities, companies, and individuals who want to examine the source code for personal interest or research & development. The licensing does not impose restrictions upon those who wish to work on independent open-source projects.
http://download.java.net/jdk6/source/
and OpenJDK source jars are here

Using Java Compiler API without requiring install of JDK

Hello All
I am writing some software that will allow users to create their own Java classes for a specific use in my software package. Obviously, my software will need to be able to invoke a Java compiler to compile the user-generated classes for use in my program. However, I do not want to require users to download and install the entire JDK just so they can have access to the javac Java compiler. I understand that in Jave 6 there is a new Java Compiler API but even then, users with just the JRE and not the JDK will get a null object when they try to instantiate the Java compiler tool.
So, what is the best way to enable my program to compile Java classes while requiring the end user to just have the JRE installed on their machines? If this is not possible, what is the minimal set of libraries/jar files I would need to install on the user machine?
I suppose another possibility might be to use JWS (javaws) to launch the app over the web. In this case, is it possible for my software to not require the JDK (mainly tools.jar I think)? Would I somehow have to bundle tools.jar with my software?
You can use standalone Java compiler from Eclipse. It doesn't need JDK installed, and it's single JAR file you can use in your project. This is the compiler that is used inside Eclipse itself, but it can be integrated into other programs too. You can find current latest stable version at http://download.eclipse.org/eclipse/downloads/drops/R-3.6.2-201102101200/index.php, look for Look for JDT Core Batch Compiler. Documentation is available at http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.jdt.doc.isv/guide/jdt_api_compile.htm
You can also use Janino, which can compile also smaller units than full Java classes: blocks, expressions. It's not full compiler though, it does not support all features of Java language that your users use (generics, annotations, enums, ...)
To use the java compiler, you need to include tools.jar into your application (e.g. it has to be reachable by the classloader who wants to load the compiler - most easily by the System class loader).
Maybe http://asm.ow2.org/ this will be usefull? To generate bytecode on fly?
It sounds like a better solution would be to use some scripting language that can run within the JVM without having to be compiled.
Possible the Java Scripting API would be of use to you. I'm sure there are other options as well.

Deploying Application with JVM

Our customer wants us to ship his application with an embedded JVM. We tried to convince him otherwise but had no luck.
Now, here is the way we are contemplating taking. We want to take the Apache Harmony VM and libraries. We would then strip everything we don't need and ship the application with the bare minimum in terms of libraries.
My questions are thus:
1) Where can I find detailled explanations about the functionality provided by the different libraries (natives and classes) coming with a JVM?
2) How can i know if a JVM library file is needed or not?
I know the questions are a bit convoluted, but i hope somebody out there have done something similar.
Regards,
Gregoire.
It looks like you can also distribute the Sun JDK if you do not modify anything (I would consult a lawyer to be sure).
Whichever way you go I would not prune anything, that would make it more complicated if and when you needed to upgrade the client's software.
The problem is not the license of Sun/Oracle, they allow redistribution of the Java Runtime Environment, so developers can embed it into their application installation packages.
However, the problem is export regulations. By law, you may not export parts of the JRE to certain countries, so you would have to check whether your customers are in the allowed list of countries before they can download your application package which includes the JRE. This for example applies to such things as the Java Cryptography.
Use a Sun JVM embedded within your application and start it with the invocation API. That way you could save some more diskspace :) IBM has an example source code how to start the JVM.
Try launch4j to bundle the JVM with your application and save some work.

Tool for checking source for dependencies on specific Java versions

Is there a quick way (e.g. tool) to detect, from the source (or maybe even from compiled classes), which parts of an application call Java API methods that are only implemented in a specific Java version? (e.g. which parts of my app are Java6-specific)
I don't necessarily want to hop through all ClassMismatchErrors and avoid the trial-and-error-method. Let's say I only want to document which parts of an application won't work if they were writte for, e.g., Java6 and I want to run it in a version 5 JDK.
Is there something like this? Google did not help this time, nor did I find any solution here (a rare case indeed:)
The Animal Sniffer might be helpful for this, especially its Maven plugin.
If I understand you correctly, what you're describing doesn't sound like a very good idea to me.
It sounds like you want to build some library on JDK 6 (specifying -target 1.5), but let it be run on JDK 5 and just have certain classes or methods here and there just not work (because they needed a Java6-only API). I wouldn't do this. A method which should work might still trigger a class to be loaded which itself contains some reference to a class that's new in Java 6, and an Error will be thrown.
It's much better if you just choose which version is your minimum supported version and live with that.

Categories