|
Evaluation
|
In fixing this bug I plan to do the following things to cleanup the Java RPM packages in general:
*** Reduce Duplication of Code ***
- Currently there are separate RPM package specification files for the JRE and the JDK. However, the only real differences in these individual specifications is in the values of a few fields. These files, rpm-jdk.spec and rpm-jre.spec, should be combined into a single RPM package specification file that can be used to build either package.
The new specification file, named generic-rpm.spec, should use 'keywords' to represent text that is unique for a particular JDK/JRE package. The Makefile should be changed to replace the keywords, for example, by using the 'sed' command, with the correct text for the JDK and JRE targets at build time.
For example, the Makefile will replace the keyword "RPM_PKG_NAME" in the specification file with the text "jdk" or "jre" using 'sed' depending on whether it is the JDK/JRE targets respectively. Doing this for all JDK/JRE unique text removes the need for separate package specification files.
- Shell scripts should generate the text description for the RPM packages. This will A) ensure that the descriptions are formatted nicely, B) assist in making a single package specification possible, and C) make it possible to get the short, medium, and long version of the public (i.e. marketing) name for each package from a single location.
Note: these names will initially come from the RPM package bundles Makefile. However, later in Mustang other changes are planed to centralize the location for name strings to simplify the process of any future changes to the names.
- Currently a lot of shell script is duplicated in multiple places within the RPM package specifications. For example, the code to add/remove GNOME MIME-type integration is needed in both the post-install, and post-uninstall RPM package scriptlets. This duplication makes it possible for a change to be made in one place, but forgotten in another.
Instead of duplicating scripts it would be better to write them once as a macro , and use them wherever they are needed. RPM does not provide much capability for creating multi-line macros within an RPM package specification file (formatting becomes an issue quickly). However, it is possible to create a macro that behaves somewhat like a C/C++ include statement.
By using the RPM macro directives "expand:" and "%%(<shell-command>)" it is possible to generate a macro that contains all the text of a separate file. This technique should be used to replace the existing inline scripts, plus any new scripts that are required for adding the default and latest Java links to Linux. The existing scripts should be placed into separate files that are named by their functionality. For example:
filename functionality
------------------- ----------------------------------------------
unpack_jars unpacking pack200 JAR files
legacy_mime_support Netscape MIME-type integration for JavaWS
gnome_support GNOME file extensions/MIME-types integration
parse_release_info Java name/version parse, sort, compare support
link_support support for symbolic links
Note: an advantage to breaking the scripts into separate files is that they can be unit tested outside the RPM build environment. They can also be included in other scripts using the shell 'source' command. This provides the potential to eliminate more duplication by possibly using the same script text in other bundles, such as the Unix self-extracting bundles, or possibly even the Solaris SVR4 packages.
Note: due to limitations in the version of RPM currently used to build Java on the Linux AMD64 (x86_64) platform, it may be necessary to break these files into pieces. In this case, each piece of the file will be given the extension '.partN' where N is from 1 to X, where X is the total number of parts. At a later time when the AMD64 platform is upgraded, these parts should be merged back together.
*** Stop Fixing Past Mistakes ***
There are problems in past Java RPM package scripts that break the system integration setup by other versions of the Java packages. Some of these problems are bugs, others were caused due to an insufficient level of experience in creating RPM packages.
Most RPM package bugs are not critical enough to justify backporting fixes to update releases. However, in the past, some effort has been made in version Y to fix problems caused by version X. In general, this effort has only succeeded in making the RPM package specification scriptlets extremely complex.
In the process of implementing the changes for default and latest Java links, the RPM install process should be simplified. The process should always do whatever is necessary to make the version being installed functional. This typically means creating and populating the Java install directory, ensuring that the files required by the Preferences API exist, and using unpack200 to unpack packed JAR files.
The first two parts can be done automatically by RPM without any pre/post install scriptlets. Using a properly defined %files section within the RPM package specification will ensure that the Java install directory is relocatable, and populated, and that the minimum support for the Preferences API exists (without overwriting pre-existing preferences). (Note: providing a proper %files section also has the benefit of fixing CR 4887372 and 5109119.)
The third part, unpacking JAR files, can only be done with a post-install scriptlet. However, this is also the only thing that *must* happen in every post-install. All other integration should only occur when the version of Java being installed is also the "latest" version. Only in such a case should a default/latest link be created, or any other integration, such as GNOME or Netscape MIME-type integration.
Past packages attempt to do integration with every install. The idea is to "fix" a broken install even when the current install isn't the latest. However, what is correct integration today, most likely won't always be correct. When a package sets integration for a package other than itself, it could be setting old, unsupported integration that the newer package cannot later fix/use/remove.
It is best to only setup additional support functionality only when the package being installed is known to be the latest package on the system. For this same reason, the uninstall scripts should be equally simple.
The uninstall scripts should always remove any changes made by the install. The only time a change made by a package's installer shouldn't be removed by the package's uninstaller is when the same version of the opposing package is still on the system. For example, if JDK version X is being uninstalled, it should remove all changes unless JRE version X is also installed. In which case, it must still remove any changes that wouldn't normally be removed by the JRE version X uninstaller.
*** Provide a Verify Scriptlet ***
The RPM package specification should define the %verifyscript scriptlet. By using the '--verify' option, this scriptlet can be invoked by an administrator at any time after an RPM package is installed. Java RPM packages should use the verify scriptlet to ensure that Java is properly integrated into the system.
The verify script should test to determine if the version being verified is the latest version. If it is the latest version, it should do all the things that the post-install script does when the latest version is installed. Otherwise, the script should do nothing.
The purpose of the verify script is to provide administrators with a method of fixing a broken install that is caused by problems in past Java RPM packages. Instead of trying to fix these mistakes in the install/uninstall scripts, they should only be fixed in the verify script. There are several reasons for this:
1) RPM --upgrade does the following:
* run the pre-install scripts for the new package
* install the package's files
* run the post-install scripts for the new package
* run the pre-uninstall scripts for each old package
* remove any unused files from each old package
* run the post-uninstall scripts for each old package
This means that it is impossible for a post-install script to fix a problem that is caused by an older packages pre/post uninstall scripts.
2) RPM --install --force can be used to install an older version of a package onto a system that already has the latest version of Java. The old version was released long before the current version, and knows nothing about how the new version integrates additional functionality. It is quite likely that it will break some of this functionality. Without a verify script, an administrator would be forced to uninstall/reinstall the latest version.
*** Stop Using EPOCH Tags ***
The JDK RPM package specification currently specifies a EPOCH tag. This tag should never have been used. It is one of the causes for CR 6177499. An EPOCH (or "%Epoch:" in the code) causes RPM to ignore all other version information when making comparisons, i.e. 0:name-1.5.0 = 0:name-1.6.0. The JDK/J2SDK have used the *same* Epoch for *all* releases. This means j2sdk-1.3.0 = j2sdk-1.3.1 - j2sdk-1.4.0, etc...
Note: Removing the EPOCH does not fix 6177499. It could be argued that I shouldn't make this change until I fix 6177499. However, in my reading, the use of EPOCH is so proscribed, I think we should stop it's use immediately.
xxxxx@xxxxx 2005-04-14 20:35:59 GMT
FYI, it seemed to me that greenrd made a good argument for keeping the EPOCH, so that is what I'm doing for now.
As to the comment about using 'alternatives', that API is not supported by all platforms Java is required to support. Specifically it is not supported by SuSE based distributions.
xxxxx@xxxxx 2005-05-17 01:21:01 GMT
|
|
Comments
|
Submitted On 22-APR-2005
wormbin
I've been very pleased with the way gentoo linux allows the user to easily have multiple java/jdk versions installed and easily switch between them. Although this feature seems RPM centric, maybe something can be learned from gentoo's implementation:
http://www.gentoo.org/doc/en/java.xml
Submitted On 22-APR-2005
greenrd
www.jpackage.org already has a multi-vendor solution for switching between JDKs and JREs - it uses the
Submitted On 22-APR-2005
greenrd
Let's try that comment again.
www.jpackage.org already has a multi-vendor solution for switching between JDKs and JREs - it uses the 'alternatives' program. This is a good solution, and I highly recommend you attempt to replicate it precisely. Doing so would have the advantage that it would not screw up the installations of people who already use jpackage's java-1.x.x-sun-compat packages.
I would _not_ recommend removing the epoch. Red Hat and jpackage.org _do_ both still use it. Keeping it the same forever may be ugly, but is guaranteed to work. Removing it, may confuse some tools.
Submitted On 25-APR-2005
bborud
whatever you do, do not complicate it further. I don't think this belongs here at all. this is not really something Sun should be concerned with. this is something the distro developers should care about.
the last thing I want is yeat another
Submitted On 11-JAN-2006
fuckoffcunt
This bug is ridiculous. This is what the linux systems have a PATH for
To quote:
> Just say 'java' and something happens. The linux experience should be similiar.
That part is already handled simply by having the path to java/bin in the PATH (either set up by the user or by the system config files).
The next part of the bug states:
> Currently Linux applications have to hardwire the version into the path (because the version is in the path).
An application only has to specify the path to java if the user
has not got their PATH set up correctly, or if the application
DOES want to run a particular version.
No matter what you do, it will always be the case that a 'java' must be installed in the PATH if you want to run java by just typing java. All you can change is whether the java that runs is a particular version of java or some wrapper binary/script which uses some other method to determine which real j2sdk-xxx/bin/java to run.
I guess this is what you were thinking of putting in /usr/bin/java ?
If so then what it seems to come down to is you want to install a program called java in a bin directory which is usually in the default system PATH. So what do you want to do when java is installed in /usr/local or /opt, or when a user wants to install it in their own home directory somewhere for their own use? Applications installed in /opt should not go installing stuff into /usr/bin.
As other people mentioned, those sorts of issues are best handled by the various distributions, and have been handled fine up to now.
I really hope that whatever was done to fix & close this bug will only affect those using RPM packages. It would be a real shame if I ran /opt/j2sdk1.5.0/bin/java and it went off and through some complicated logic decided to run a different version.
Submitted On 10-DEC-2007
The RPM should include some instructions about changing the default location of the java executable (or should change the location itself). I just installed Java 6 on Red Hat and the active java executabe was still pointing to the alternative location of Java which came with the OS located in /etc/alternatives/java. This was because of a symbolic executable link /usr/bin/java which was pointing to /etc/alternatives/java. An inexperienced user may neglect to change the symbolic link at /usr/bin/java from /etc/alternatives/java to /usr/java/default/bin/java.
The RPM should either go ahead and make that change itself or leave a message for the user at the end of the install alerting to the fact that the default java executable is not the one they just installed.
Also, is there any home in this for a system variable like JAVA_HOME=/usr/java/jdk6 that can be included in the system path, like PATH=$JAVA_HOME/bin.
That might be too standard for everyone to agree on.
-FannyTitBumEars
PLEASE NOTE: JDK6 is formerly known as Project Mustang
|