Which parts or packages can be removed from JDK? - java

There are a lot of packages built in the jdk, and the size of jdk is biger and biger. But I found there are a lot of packages I never used, or they have a better 3rd party replacement.
So, which packages do you think can be removed from JDK, or we don't need to use them?

So, which packages do you think can be removed from JDK, or we don't need to use them?
Unless you mean this as an subjective question of what "we think is superfluous" (in which case the question should and will get closed quite quickly), you are the only one able to tell which packages you don't need.
I'm not sure though, why you would want to strip down the JDK. The JRE would perhaps make more sense to strip down on a system with really limited resources. If you wish to do this, Google provides many good urls.

So, which packages do you think can be removed from JDK, or we don't need to use them?
I don't think a cut down JRE is a good idea.
Lets think about the reasons why you might want a cut down JRE:
"The size of a JRE is getting bigger". But the size of hard disks is getting bigger more quickly.
"The size of JRE installers is getting bigger". But the speed of networks is getting faster more quickly.
"The JRE is using more and more memory". Most likely it isn't. A running Java application only loads the JRE classes that it actually uses. A command line "hello world" program does not pull in Swing, CORBA support, the XML parsers, or anything else that it doesn't use.
"But it is using too much memory". Really? If you think so, consider using Java ME .... and learn to live with the downside of a cut-down class library.
And to answer your question. I don't think any of them should be removed. They are all useful to a lot of people some of the time. And if any of these packages were removed, from the standard JRE it would break compatibility for many, many existing applications.
And the packages cost very little in the case where they are not actually needed. At least, not in most use-cases.
In reality, Sun/Oracle have done a lot of work to reduce footprints and improve JVM startup times. And last time I looked, more work on this was on the agenda for Java 8.
If you are considering doing this for yourself, here is some free advice:
DON'T DO IT.
IANAL, but I understand that creating and shipping a cut-down binary version of the JRE is a violation of the Java software license, and of the conditions under which you are permitted to use trademarked terms like Java, JRE and so on.

The first thing that comes to my mind is the project Jigsaw I'm not sure whether it is still active, but should still be a good starting point.

Related

What are the performance implications of using a JAR with an older language level in a modern project?`

I work in a corporate environment with several widely-used, infrequently-updated Java libraries in its repositories. Some of the libraries quite old, and were compiled using language levels as far back as JDK 1.5 (Java 5).
Nearly all of our actively developed Java projects are using Java 8 or newer, but they are dependent on one or more of the JDK 1.5-level JARs.
Are there performance penalties for using JARs with very old bytecode versions? Can the modern JIT update old, inefficient bytecode on the fly?
Remember: Write Once, Run Everywhere! In your case, the slogan really fits.
Generally, there's no reason to touch old Java code if it's doing its job.
The bytecode hasn't changed much over the years, the bytecode instructions understood by a Java8 JRE are 99% the same that were present already in Java2 - there were very few additions, so from that point of view there's no need to update the old bytecode. It will run even faster under Java8 than under Java5, as both the JRE with its HotSpot engine and the class library have improved a lot.
The changes in the class file format are more about metadata, and the class-file version number also makes sure that you don't run a Java8 program under a Java6 JRE where half of the Java classes and methods are missing.
What changed a lot, is the Java class library and the source language. And as an old library couldn't know about the changes to come later, it might turn out to be less efficient than a newly-written version using all the features from later Java releases. But my guess is that the performance gained by a redesign of the old libraries isn't worth the effort.
And finally the general advice on performance questions:
If it ain't broken, don't fix it (= don't optimize before you know that you have a performance problem).
Before optimizing, use a profiler to find out where your bottlenecks are. Believe me, the bottleneck is hardly ever where you expect it.

Is it OK to modify rt.jar?

I'm creating an application that launches the JVM (using a copy of the JRE). If I edit rt.jar, for example to remove functionality that users shouldn't have access to, will it somehow break the JRE?
EDIT: The application involves downloading code onto a user's machine, so it would be restricting the code rather than the user. I probably should have clarified that.
There's a good chance you would break something that won't be noticeable until runtime.
But perhaps more important is the licensing problem: your app is shipping its own version of the JRE, which you're allowed to do, except you cannot modify the JRE you're distributing, as per the J2SE license:
[...]
(a) you distribute the Software complete and unmodified and only
bundled as part of Your applets and applications ("Programs"),
It's also questionable what is meant by "to remove functionality that users shouldn't have access to". Your application is executing in the context of a user account, and whatever functionality you removed from the JRE:
If the OS allows that particular action in the context of that user's session, then there's another way to do it - hence you're in the same position you were in before messing with rt.jar. Your user can just make a system call.
If the OS doesn't allow that action in the context of the user's session, then the JVM won't be able to do it either, whether the classes are present or not, so the whole question is moot.
Usually, the best way to remove functionality is to use a SecurityManager. This allows you to control what can be accessed or key action can be performed.
Completely depends on what you "remove". But its possible. As long as you dont break anything, remove dependencies etc...
And if you want to do something security wise. How can you ensure that you and only you have full control over the users JRE?
And if this is the case. What benefit would your doing do what you can't do in your application?
But its possible and a valid thought for some reasons. But they are mostly benchmarking, developing, debugging. For example dumping unencrypted bytecode
Also be aware of the licensing problem. You probably won't be legally able to sell or ship this.
why do you ask, you might potentially break some agreement/license, other than that it's ok.
I don't do so that but change the bootstrap loader's classpath to load my classes before rt.jar, etc. This is legal :)
In the end: Getting NoClassDefFoundError aint cool, no matter how you look at it.
If you're asking if it's legally okay, I don't know but chances are that it isn't. (If you're intending to sell your product, that is. For research or recreational uses it probably is.)
Is it okay technically? If you know what you're doing, it can be.
Does it make sense though? How hard it is for the client to install another VM or just replace your hacked rt.jar with an unhacked one?
And on a more abstract level: is it a good idea to treat your customers like potential criminals? To assume that the first thing they're going to try is to hack your system. (Mind you, I don't know your customers, so you might as well be right, but the question is worth asking nevertheless.)

Should I be concerned with large number of dependencies?

I was just about to include the HtmlUnit library in a project. I unpacked the zip-file and realised that it had no less than 12 dependencies.
I've always been concerned when it comes to introducing dependencies. I suppose I have to ship all these dependencies together with the application (8.7 mb in this particular case). Should I bother checking for, say, security updates for these libraries? Finally (and most importantly, actually what I'm most concerned about): What if I want to include another library which depends on the same libraries as this library, but with different versions? That is, what if for instance HtmlUnit depends on one version of xalan and another library I need, depends on a different version of xalan?
The task HtmlUnit solves for me could be solved "manually" but that would probably not be as elegant.
Should I be concerned about this? What are the best practices in situations like these?
Edit: I'm interested in the general situation, not particularly involving HtmlUnit. I just used it here as an example as that was my current concern.
Handle your dependencies with care. They can bring you much speed, but can be a pain to maintain down the road. Here are my thoughts:
Use some software to maintain your dependencies. Maven is what I would use for Java to do this. Without it you will very soon loose track of your dependencies.
Remember that the various libraries have different licenses. It is not granted that a given license works for your setting. I work for a software house and we cannot use GPL based libraries in any of the software we ship, as the software we sell are closed source. Similarly we should avoid LGPL as well if we can (This is due to some intricate lawyer reasoning, don't ask me why)
For unit testing I'd say go all out. It is not the end of the world if you have to rewrite your tests in the future. It might even be then that that part of the software is either extremely stable or maybe not even maintained no more. Loosing those is not that big of a deal as you already had a huge gain of gaining speed when you got it.
Some libraries are harder to replace later than others. Some are like a marriage that should last the life of the software, but some other are just tools that are easily replaceable. (Think Spring versus an xml library)
Check out how the community support older versions of the library. Are they supporting older versions? What happens when life continues and you are stuck at a version? Is there an active community or do you have the skill to maintain it yourself?
For how long are your software supposed to last? Is it one year, five year, ten year or beyond? If the software has short time span, then you can use more to get where you are going as it is not that important to be able to keep up with upgrading your libraries.
It could be a serious issue if there isn't a active community which does maintain the libraries on long term. It is ok to use libraries, but to be honest you should care to get the sources and put them into your VCS.
Should I bother checking for, say, security updates for these libraries?
In general, it is probably a good idea to do this. But then so should everyone upstream and downstream of you.
In your particular case, we are talking about test code. If potential security flaws in libraries used only in testing are significant, your downstream users are doing something strange ...
Finally (and most importantly, actually what I'm most concerned about): What if I want to include another library which depends on the same libraries as this library, but with different versions? That is, what if for instance HtmlUnit depends on one version of xalan and another library I need, depends on a different version of xalan?
Ah yes. Assuming that you are building your own classpaths, etc by hand, you need to make a decision about which version of the dependent libraries you should use. It is usually safe to just pick the most recent of the versions used. But if the older version is not backwards incompatible with the new (for your use case) then you've got a problem.
Should I be concerned about this?
IMO, for your particular example (where we are talking about test code), no.
What are the best practices in situations like these?
Use Maven! It explicitly exposes the dependencies to the folks who download your code, making it possible for them to deal with the issue. It also tells you when you've got dependency version conflicts and provides a simple "exclude" mechanism for dealing with it.
Maven also removes the need to create distributions. You publish just your artifacts with references to their dependents. The Maven command then downloads the dependent artifacts from wherever they have been published.
EDIT
Obviously, if you are using HtmlUnit for production code (rather than just tests), then you need to pay more attention to security issues.
A similar thing has happened to me actually.
Two of my dependencies had the same 'transitive' dependency but a different version.
My favorite solution is to avoid "dependency creep" by not including too many dependencies. So, the simplest solution would be to remove the one I need less, or the one I could replace with a simple Util class, etc.
Too bad, it's not always that simple. In unfortunate cases where you actually need both libraries, it is possible to try to sync their versions, i.e. downgrade one of them so that dependency versions match.
In my particular case, I manually edited one of the jars, deleted the older dependency from it, and hoped it would still work with new version loaded from other jar. Luckily, it did (i.e. maintainers of the transitive dependency didn't remove any classes or methods that library used).
Was it ugly - Yes (Yuck!), but it worked.
I try to avoid introducing frivolous dependencies, because it is possible to run into conflicts.
One interesting technique I have seen used to avoid conflicts: renaming a library's package (if its license allows you to -- most BSD-style licenses do.) My favorite example of this is what Sun did when they built Xerces into the JRE as the de-facto JAXP XML parser: they renamed the whole of Xerces from org.apache.xerces to com.sun.org.apache.xerces.internal. Is this technique drastic, time consuming, and hard to maintain? Yes. But it gets the job done, and I think it is an important possible alternative to keep in mind.
Another possibility is -- license terms abided -- copying/renaming single classes or even single methods out of a library.
HtmlUnit can do a lot, though. If you are really using a large portion of its functionality on a lot of varied input data, it would be hard to make a case for spending the large amount of time it would take to re-write the functionality from scratch, or repackage it.
As for the security concerns -- you might weigh the chances of a widely used library having problems, vs. the likelihood of your hand-written less-tested code having some security flaw. Ultimately you are responsible for the security of your programs, though -- so do what you feel you must.

Can I compile java myself?

Is they say that sun's java is opensource now - then can I compile all the patform from sources ?
I used gentoo and I found a great performance inmrovement wnen I compiled the system myself, so can it be done with java (both vm runtime and library classes ) ?
Is it possible to do under windows/linux ?
Did anyone do it ?
Does it make any sense ?
Yes you can. Prebuilt binaries, source code etc. are available in the OpenJDK project from Sun:
http://openjdk.java.net/
Whether it makes a difference to performance is hard to tell. It might, but usually the difference is not great.
yes, that should be possible now -- and no, it will not give you any benefits unless you have a compiler that produces better byte code from the same source input. Given the simple nature of translating java to bytecode and the fact that most optimizations are done at runtime, that seems unlikely.
Yes it's possible. If you check repositories for your linux distribution you will notice there is usually the option for OpenJDK. Everything you're after can be found on http://openjdk.java.net/.
I am not quite sure why you would want to do this, other than for educational purposes.
Sun put quite a lot of effort in performance improvements in all aspects (JVM as well as default libs) and I see no reason why you would get it better.
Again, it's nice to know how to do it, but I wouldn't expect huge performance improvements.
I would start looking here for your java jdk sources.
Java compiles the programs to machine code, and from what I have gathered at the Sun web site, it is quite sensitive to which compiler is used. Hence you need to use a supported build environment to be certain that the result is 100% correct.
Building the JDK is NOT easy for the uninitiated so unless you feel at home reading Makefiles I would leave this project for later :)

What is classpath hell and is/was it really a problem for Java?

What is classpath hell and is/was it really a problem for Java?
Classpath hell is an unfortunate consequence of dynamic linking of the kind carried out by Java.
Your program is not a fixed entity but rather the exact set of classes loaded by a JVM in a particular instance.
It is very possible to be in situations where the same command line on different platforms or even on the same one would result in completely different results because of the resolution rules.
There could be differences in standard libraries (very common). Libraries could be hidden by one another (an an older version may even be used instead of a newer one). The directory structure could mess resolution. A different version of the same class may appear in multiple libraries and the first one encountered will be used, etc. Since Java, by specification, uses a first-encountered policy, unknown ordering dependencies can lead to problems. Of course, since this is the command line and it is part of the spec, there are no real warnings.
It is very much still a problem. For example on Mac OS the horrible support from Apple means that you machine ends up with several JVMs and several JREs, and you can never easily poart things from place to place. If you have multiple libraries that were compiled against specific but different versions of other libraries, you coulld have problems, etc.
However, this problem is not inherent in Java. I remember my share of DLL hell situations while programming windows in the 90s. Any situation where you have to count on something in the file system to assemble your program rather than having a single well defined executable is a problem.
However, the benefits of this model are still great, so I'm willing to tolerate this hell. There are also steps in the right direction on the side of Sun. For example, Java6 allows you to simply specify a directory with jars rather than have to enumerate them.
BTW: Classpaths are also a problem if you are using an environment that uses a non-default classloader. For example, I have had a lot of problems running things like Hibernate or Digester under Eclipse because the classloaders were incompatible.
Classpath/jar-hell has a couple of escape hatches if they make sense for your project:
OSGi
JarJarLinks
NetBeans Module System - Not sure if this is usable outside of NetBeans
Others?
I think "classpath hell" refers to the time when the classpath of a Java app could only be set by using the CLASSPATH environment variable. This led to many applications requiring changes to the global system configuration (different for each OS), version conflicts between applications, and general confusion.
This is a somewhat more concrete example:
When two libraries (or a library
and the application) require different versions of the same third
library. If both versions of the third library use the same class
names, there is no way to load both versions of the third library with
the same classloader.
Take a loot at http://en.wikipedia.org/wiki/Java_Classloader#JAR_hell for more examples.
There's lot of good stuff here http://mindprod.com/jgloss/classpath.html and http://java.sun.com/javase/6/docs/technotes/tools/windows/classpath.html
I've only had issues with classpaths when I am not setting is myself using -cp. Trying to figure out how your third-party software sets their classpaths can be a pain at times.

Categories