Updating gzip library in jre - java

Is there a way to update gzip library that JRE uses?
There is a bug in gzip library that is used by latest JRE, and it has been fixed in later version of gzip library, so I would like to make latest JRE work by updating just gzip.
Bug is in a native code from gzip library that JRE uses.

Basically no (but you can probably do operating system magic to override the native library loader to include the new one).
Have you located this issue in the Java Bug Database? http://bugs.sun.com/

I think it's possible by setting the bootclasspath: http://java.sun.com/javase/6/docs/technotes/tools/solaris/java.html to override the class with the newer version.
Please read the warning: "Applications that use this option for the purpose of overriding a class in rt.jar should not be deployed as doing so would contravene the Java 2 Runtime Environment binary code license."
(Or if the bug is located in a native library, you could use java.library.path)

The short and simple answer is "no". At least you would not want to go there for all sorts of reasons.
Unfortunately Commons Compress also only uses the native compressor from java.util.zip but in your case I would still use Commons Compress so the compressor becomes easy to replace from the API point of view. Then write your own Compressor. In java if you don't need the speed or using JNI if want to really go for it. As soon as the bug is fixed in the JRE you can just switch the implementation back to the JRE one.

Related

java.nio.Files, java.nio.Paths on java 6

I need to rewrite some java 7 file IO code that should run on a Java 6 VM too.
The implementation uses handy Java 7 features like autoclosing, Paths and Files.
To be more specific, I need to handle expressions like /tmp/foo/*.bar to return all .bar files (currently implemented with Files.newDirectoryStream(dir, glob)).
Does anyone know a handy library for this?
The Apache Commons IO API is also a good choice. I used it for a similar work (rewrite some code from java7 to java6 that used Path object) and they work very well.
The Apache Ant API would be a good candidate for this, in particular their FileSet class might do the job.
guava runs on java6 and it has a nice I/O api.

Java Version Compatibility Issue

I have a client jar made-up using java 1.6 and used enum and other new features of java, my application is built on java 1.4.
I want to use that client jar in my application.
Is it feasible to do ?
Normally: no, you can't.
You could use a library/byte-code rewriter like Retroweaver to rewrite the library to be 1.4 compatible. There's also Retrotranslator which does the same thing and other tools. The last time I used Retroweaver was just after Java 5 was released, so I can't talk about it's current state.
But that will be a hack at best. Using an ancient Java version is a liability at best and you should upgrade to at the very least Java 5 as soon as possible.
Can't you upgrade to JDK1.6?
else you need to add rt.jar of JDK1.6 to your class path but that will cause conflicts for classes common to JDK1.4 and JDK1.6
Your client jar will need JRE 1.6. As for your application, ideally you should be able to run it on JRE 1.6 as Java is backward compatible.
So you need to port your application to JRE 6, recompile and then you should be able to use client jar.
However, upgrading and porting has it own complexity and consequences.
you could try making the jar available via a web service interface and run it as 1.6; should work, but I won't tell you it 'll be easy.
You obviously need JRE 1.6 or higher to run your library code. Due to backward compatibility the 1.4 part of your application should run on a that JRE as well. How you interact between your 1.6 lib and your 1.4 application is another question though.
Your application cannot use enums or other 1.5 features directly. If everything you directly access in your library is 1.4 compatible it should work, I think. E.g. if your application defines an interface and the library provides an implementation of that. (I.e. typical plugin pattern.) If your library's interface needs the application to use 1.5 features, e.g. pass an enum value as method parameter, that obviously won't work with your existing byte code.

How do I know whether my Java application uses "native code"?

On a recent question, I got comments asking whether I was using "native code" in my application. Now, I know that there is some way to call code in traditional binary libraries (DLLs, SOs) from inside a Java application using a thing called "JNI". I have read that Wikipedia entry but I never used this.
I am using a number of libraries, some of which may or may not use native code. How do I find out if they do? I did not have to install any SOs (running on Linux), but I guess that doesn't mean the libraries are not using any? Do I have to browse through all the documentation (which varies greatly in quality between libraries) or can I do some analysis on the JARs?
Usually using libraries that require JNI requires some additional setup (like putting .dll or .so files in the right places or setting the java.library.path System property).
If you did nothing of that, then chances are that you're not using JNI anywhere. This is also somewhat likely, as only quite specialized libraries require JNI.
However there's also JNA, which is a wrapper around JNI which simplifies its usage and which sometimes makes it unnecessary to do any explicit setup. If that's used by one of your libraries, then it's harder to detect.
If you get a crash dump, then checking that for any non-standard libraries can give a hint if a user-loaded native library is to blame.
To nitpick, every single Java application uses JNI indirectly at least. For example, System class contains several native methods, which map to the native JRE (as can be seen from its source code).
Whether your program/libraries use (directly or indirectly) some other native functions than those contained in the standard JRE, is indeed hard to detect. The .dlls / .sos may be packed into the .jar, to be extracted only when needed, so not having to install native libraries doesn't guarantee that it doesn't use any. It should usually be stated in the library documentation, though, because the vendor probably won't provide binaries for every imaginable system that Java runs on. But to be sure, I think the only way is to scan through the source code for native methods.
If a java library (jar) uses a native library (dll on Windows or so on Linux) the chances are that it is a system wide and well known library (such as glibc on Linux) or a custom one. In the last case it is common to pack it within the jar, so you can just open it up with a ZIP decompressor (i.e. 7zip on Windows will do fine) and browse the files. You should see dll files if it is targeted to Windows, so files if targeted to a Unix platform, or even both. The native library files usually are left at the root level of the jar.
If the jar uses custom libraries but it is packed along with an application it is common to leave the native libraries in an external folder with other application files (in this case there is no consensus). In this case you should look for the application launcher (a bat / sh file) or the configuration file if the lanucher is binary (an ini / conf file) and find out the JVM configuration (where java.library.path points to).
Probably the easiest way of doing this is using jmap or pmap to show which .so (shared object) files are mapped into your Java process. If there's anything other than stuff that's in /lib, /usr/lib or the Java lib directory it's a JNI suspect. You can also look at the /proc entry for the Java process under /proc/<pid>/maps. See the following manpages:
http://linux.die.net/man/1/jmap-java-1.6.0-openjdk
http://linux.die.net/man/1/pmap
http://linux.die.net/man/5/proc

Open Office Spellchecker / Java API

Is it possible to make use of the Open Office spell-checker outside of Open Office for other Java programs?
Walter
We have done exactly that - used the hunspell engine from java. There is a JNA bridge that can be used to invoke hunspell from java. Very nice to use - takes care of loading the appropriate native library from the jar.
The only problem is that the bridge is not updated with the latest hunspell engine - it is at version 1.1.12, and at the time I looked (last year), hunspell was at 1.2.18, which contained fixes we needed. It's not a big deal to build the hunspell libraries and rebuild the JNA wrapper with the latest hunspell engines, although it does involve cross-platform compilation. IIRC we used a windows box and a linux box to rebuild both those platforms (cygwin on windows didn't cut it) and we didn't need the version for OS X. I can let you have what we built if that's useful.
See
Java API for Hunspell
jna.dev.java.net
OpenOffice simply uses hunspell for the spell checking - you should investigate it instead. Its home page mentions the existence of two java interfaces/ports.

Switching between bytecode versions for a Java class file

Given a Java class file (ClassName.class) with bytecode version X is there a general way to convert this class file from being represented in bytecode version X to being represented in bytecode version Y?
Assumptions:
The source code is not available. The class file is the only available representation of the class.
The class file is heavily obfuscated, so decompiling the class with say jad or similar program and then recompiling it with "-target ..." does not work.
Updates after initial post:
Update #1: Futhermore, assume that bytecode version X and bytecode version Y are sufficiently close so that all instructions used by the class (currently in bytecode version X) also exists in version Y.
For downgrading you can have a look at various methods to get Java 5/6 code running in Java 1.3/1.4. See my anwser to related question Backport Java 5/6 features to Java 1.4?
You could use Apache BCEL
The Byte Code Engineering Library is
intended to give users a convenient
possibility to analyze, create, and
manipulate (binary) Java class files
BCEL gives you the possibility of reading in a class file of a given version, manipulating it, generating a new class file stream, and then loading that into the VM using the low-level ClassLoader API. Very fiddly, no doubt, and I doubt this will let you downgrade the version as easily as you could prograde.
No. While later versions of Java will be able to execute that bytecode, you can't upgrade it: Later versions of the class files have a different format.
You can't downgrade it either because there is no way to replace the missing bytecodes by other constructs in older versions of Java.
[EDIT] IIRC, Sun added at least a single new bytecode instruction for every major version of Java. This is usually the reason for major Java releases: Changes to the bytecode.
That said, just try your luck and change the major version of the class file and see if your newer VM will load it. I doubt it will work for any complex example but you might be lucky.
Use retroweaver

Categories