openjdk-8u45-b14\jdk\src\share\classes\com\sun\java\util\jar\pack\BandStructure.java
BandStructure.java is removed in jdk11, I am upgrading to jdk 11 from jdk 8 and the above file is not present in source code of jdk 11.
Please suggest any alternative
The BandStructure does still exist in Java 11, but the Java compiler + module system now makes it harder for application code to depend on JVM internal classes.
The BandStructure class still exists in the OpenJDK codebase up to Java 13 but it is gone in Java 14. Thus class is a component of the old pack200 and unpack200 utilities that were deprecated in Java 11 and removed in Java 14.
Is there a replacement for BandStructure?
Well, in the general sense ... no there isn't. The pack200 and unpack200 commands have been removed from the codebase.
There might be a replacement for your particular use of BandStructure ... but we cannot advise you about that unless you provide more details.
If you desperately wanted to keep using BandStructure in Java 11, you could consider using --add-exports etcetera as described in JEP 261. However, this is only putting off the problem until later. By Java 14, the class is completely gone.
Note that it was always a bad idea to write applications that depended on internal classes from com.sun.* packages. The documentation has always warned that such classes could be changed or removed. In this case, it has happened.
Pack200 gone
The Pack200 feature was removed in Java 14. Thus your missing class.
See JEP 367: Remove the Pack200 Tools and API.
To avoid these surprises, I suggest:
Reading the release notes for every version of Java
Compiling and testing with each non-LTS version of Java
Related
I understand that any access to JDK Internal APIs from my project's code will be flagged by the Java compiler at compilation. But what about 3rd party library JARs compiled in Java 8.
My understanding is that since they were compiled on JDK 8 or earlier, they will end up in the classpath. The code in these classes can access the JDK Internal API at runtime. Is that correct?
This is from the JDK 9 release notes:
JDK 9 Release Notes
All JDK internal classes are also encapsulated at run-time but most remain accessible to applications and libraries on the class path. Specifically, all public classes in JDK internal packages that existed in JDK 8 remain accessible to code on the class path.
So, if my project depends on library X (compiled in JDK 8) that accesses JDK Internals, I should be good right?
No. If you rely on something which has been removed from the JDK, even indirectly, then your code which compiled fine on JDK 8 will not work at runtime on JDK 11.
You rely upon some classes which your code expects to be available on the classpath at runtime. If that expectation is not met, it will not work. Items have been deliberately removed from the JDK; they are not just hiding from the compiler, they are physically gone.
If you can be specific about the internals which you rely upon, we can give you more details about that.
I regularly use MALLET for topic modeling in the classes that I teach. Running MALLET requires users to have the Java Development Kit installed. I currently have JDK 8 update 241 installed on my main computer, and I know that MALLET works properly in this environment. That said, JDK is now up to v14.
Which version(s) of JDK does MALLET support?
I'm not altogether sure that you do need the JDK. They never say that on the website. The tarfile that I downloaded already includes compiled classes - you aren't expected to build it from source - so the JRE should be enough.
Strangely enough, the compiled classes in the class directory are targeted at 1.7 (bytecode version 51) whereas the pom indicates that it's supposed to target Java 1.6. So it's quite probable that by rebuilding it you could support an older version of Java.
In any case, the JDK is backwards compatible by design. Any version from 7 onwards will be able to run it (6+ if you were to rebuild it).
Running it on a newer version will benefit from the new features of the JDK, such as improvements to the garbage collector, so you may see some performance improvement there. If you are not concerned about that then it doesn't matter.
I try to write my code compatible with older versions of java, so it will work everywhere.
on the other hand there is very powerful tools in the new version - java 8, and I want use them.
So I'm forced to choose between compatibility or richest code.
And I'm wondering if by any chance I can write some methods in java 8, and somehow prevent the compiler of older version to ignore these methods, so my class is compatible "partially" with older version.
Thanks.
You can write two classes and use some toll like ant, maven or gradle to chose which file use for compiling with concrete Java version.
You can set the java compiler to compile against an older jdk (ie jdk 1.5) even if you use jdk 1.8. see javac source and target options
I think the short and easy answer is no.
See this thread: Can Java 8 code be compiled to run on Java 7 jvm?
You can use the java reflection api to check if methods exist in the jvm the code runs on. This allows you to make your code fail-safe even when a method or class is unavailable in the jvm. Doing this is very cumbersome however and I'm pretty sure it's not what your're looking for.
My question is if Java JDK and JREs have to be compatible to run?
I mean: will Java applications written using JDK version 8 in future work with current JRE's?
It is possible to use cross-compilation options when compiling. Do that and it will be possible to compile code with SDK 8 that is compatible with Java 1.1. It won't be very advanced code for 1.1, but it will run.
The short answer is No.
If you develop your application in JDK 8 and run it with JRE 7, you would get an UnsupportedClassVersionError.
This question is two part:
JDK vs JRE
forward / backward compatibility.
JRE is the acronym for Java Runtime Environment. JDK is the acronym for Java Development Kit: a set of tools which you use to develop Java programs. The JDK also contains a full JRE. In general there is no compatibility issue between the two. But you might want to take care not to use libraries which are only available in the JDK (for example code generation or the tools.jar)
Java itself is compiling to bytecode, which is forward compatible. That means you can use bytecode of any Java version and run it with any newer version. The other way around generally doesn't work and is checked by using the class file version ("java.lang.UnsupportedClassVersionError: Test : Unsupported major.minor version 51.0").
Then there are Java libraries, including the core libraries. So far there was never anything removed from them, so they are forward compatible. This is probably going to change with Java 9 where a very small usually unused library functions are removed.
Regarding to backwards compatibility, this is possible by setting the Java compiler to produce Bytecode of an older version. Up until Java 8, the compiler was always able to produce bytecode of the last two major versions as well. However, you might successfully compile a Java 8 source to Java 6, but not be able to run it. That is the case when you use libraries that are only available on a never Java. For such cases there is for example the maven animalsniffer plugin which will verify that when you compile against an older version, you actually only use libraries existing in said version.
I have a PowerMac and it is giving me bad version number on some .jars. I would love to make it seem like I am running Java 6. How would I spoof the version? Let me also say I am running PowerPC and Leopard
The most likely problem is that you have Java 6 JAR files and you are trying to run them on an old Java installation.
How would I spoof the version?
The answer to your question is that you can't. The way to run Java 6 specific JAR files it to use a Java 6 (or later) JRE or JDK.
The problem is that the format of Java class files has changed, and your installation can't cope with the new format. And this is not a gratuitous change that you can pretend doesn't exist. Java 6 (actually Java 5) has support for generic types, enums, annotations and other things. Assuming that the JARs contain code that uses these new language features, an older JRE simply won't know what to do with them.
There are two solutions:
Upgrade your Java installations to the required level on all machines. This is the best solution ... if it is an option ... because it means your users will get the benefit of security and bug fixes and performance enhancements. (And progress of your project won't be held back by the constraint of supporting legacy platforms.)
Compile all of your code for compatibility with the oldest version of Java that you still have to use. Either compile on the corresponding old JDK, or on a more recent JDK using appropriate -source / -target / -Xbootclasspath options ... as described by the javac manual page.
The catch with the second solution is that if the source code for the JAR files in question uses recently added Java language features or APIs, then recompiling for the older platform will fail. To fix this you will need to rewrite your code to replace the nice modern stuff with archaic stuff. Not a good solution, IMO.
The other possibility is that you are seeing corrupted JAR files. This is unlikely, but it can happen if you are using applets or webstart, and the server is delivering error pages instead of JAR files.
The third possibility is that you simply haven't configured your Mac's Java installation's correctly. Making Java 7 the default should allow you to run everything without class version problems. (Thanks #paulsm4) Note that I can't help you with that ... 'cos I don't use Java on a Mac.