FS#41883 - [java-common] Include the symlinks in the package!
Attached to Project:
Arch Linux
Opened by I Said Socks (socks) - Tuesday, 09 September 2014, 03:10 GMT
Last edited by Guillaume ALAUX (galaux) - Sunday, 12 October 2014, 20:48 GMT
Opened by I Said Socks (socks) - Tuesday, 09 September 2014, 03:10 GMT
Last edited by Guillaume ALAUX (galaux) - Sunday, 12 October 2014, 20:48 GMT
|
Details
Description:
The java-common package leaves the following (and more) symlinks untracked: /usr/bin/java /usr/bin/jjs /usr/bin/keytool /usr/bin/orbd /usr/bin/pack200 /usr/bin/policytool /usr/bin/rmid /usr/bin/rmiregistry /usr/bin/servertool /usr/bin/tnameserv /usr/bin/unpack200 /usr/lib/jvm/default /usr/lib/jvm/default-runtime /usr/lib/jvm/java-default-runtime They're created by `/usr/bin/archlinux-java fix` in the install scriptlet. This is a very dirty approach, and is in fact _broken_. What if there is a existing file, for example, /usr/bin/keytool that is part of another package? It would be silently overwritten! Also, what's the point of the /usr/lib/java-common-wrapper script? Why can't we just add /usr/lib/jvm/default to the PATH in /etc/profile.d/jre.sh and get rid of all the bin links? Then java-common would only have to include the symlink /usr/lib/jvm/default in the package, and make the jre* packages change this symlink at install time. |
This task depends upon
Closed by Guillaume ALAUX (galaux)
Sunday, 12 October 2014, 20:48 GMT
Reason for closing: Implemented
Additional comments about closing: Implemented in java-runtime-common and java-environment-common 2-1
Sunday, 12 October 2014, 20:48 GMT
Reason for closing: Implemented
Additional comments about closing: Implemented in java-runtime-common and java-environment-common 2-1
As explained in the wiki [0] packages providing JVM are asked "Not provide any link on /usr/bin, these are automatically detected and set by archlinux-java". So no existing file would be overwritten. Also pacman does not overwrites files. Insatll scriptlets would just fail!
[0] https://wiki.archlinux.org/index.php/Java#Package_pre-requisites_to_support_archlinux-java
> Also, what's the point of the /usr/lib/java-common-wrapper script
Please read the wiki page I linked especially the "One time setup" section.
> Why can't we just add /usr/lib/jvm/default to the PATH in /etc/profile.d/jre.sh and get rid of all the bin links?
This is another approach but I did not go in favor of it. This simple archlinux-java looked nicer to me. But I am still open to constructive – though late [1] – feedback.
[1] https://mailman.archlinux.org/pipermail/arch-general/2014-May/036410.html
Still, in your solution, I don't get where the "fixed" link /usr/lib/jvm/default should point at now that you include it to the java-common package. Maybe you could sum it up in a java-common version of your own and share it here?
It's not only packages providing JVM. Some other package _may_ have installed a file under /usr/bin such as /usr/bin/keytool or /usr/bin/servertool (esp. such generic names!)
> Also pacman does not overwrites files.
Yes, but only if those files being dumped into /usr/bin are actually tracked by pacman, which is not the case.
> Insatll scriptlets would just fail!
This is not true. Your archlinux-java script uses `ln -sf` to force overwrite the /usr/bin/* files, there will be no warning whatsoever.
> Still, in your solution, I don't get where the "fixed" link /usr/lib/jvm/default should point at now that you include it to the java-common package.
From the wiki you linked,
> Use script archlinux-java in install functions to set the Java environment as default if no other valid Java environment is already set
This is to say whichever random jre* package is installed first gets to set the link /usr/lib/jvm/default. While I don't quite like this, to answer your question, I think the /usr/lib/jvm/default file in the java-common package can either be a symlink to /dev/null or an empty file.
Apart from the whole complication of this whole thing, my main point against the current java-common / jre* packages is the whole bunch of untracked /usr/bin/* symlinks.
Are all those "bin" names predictable? If it's possible to get an exhaustive list of them, the easy solution would be simply to add those links to the java-common package. In fact, you don't even need to get an exhaustive list, the unsupported jre* packages can ship their own additional links. This is the easiest way to make the package "correct".
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -31,9 +31,15 @@ check() {
./test_archlinux-java
}
-build() {
- cd "${srcdir}"
+package() {
+ ln -s /dev/null "$pkgdir"/usr/lib/jvm/default
+ ln -s /dev/null "$pkgdir"/usr/lib/jvm/default-runtime
+ local f
+ for f in java keytool pack200 rmid servertool unpack200 jjs orbd \
+ policytool rmiregistry tnameserv; do
+ ln -s /usr/lib/java-common-wrapper "$pkgdir/usr/bin/$f"
+ done
install -D -m 644 profile_jre.sh "${pkgdir}/etc/profile.d/jre.sh"
install -D -m 644 profile_jre.csh "${pkgdir}/etc/profile.d/jre.csh"
install -D -m 755 bin_java-common-wrapper "${pkgdir}/usr/lib/java-common-wrapper"
You may need to change your archlinux-java script / jre* packages' install scriptlet if they don't properly check the validity of the link already.
EDIT: If we go with this, the {,un}set_bin_links functions should be removed from the archlinux-java script, obviously.
First of all it would require 3 packages (one for jre-headless, one for jre and one for jdk – see intermediate solution [0]) which in the end I found to be heavier than just one "dynamic".
But mainly this does not solve the fact that different JVM versions and vendors provide a different binary set. For instance, JDK for OpenJDK 8 has binaries jdeps and jjs that OpenJDK 7 doesn't. JDK for Oracle 8 has these but also has a jmc that none of OpenJDK 7 nor 8 has. Also in Oracle 8, jcontrol is actually named ControlPanel. As you can see on the intermediate PKGBUILD [0] I then came up with a minimum list of common binaries to be provided by JVM packages, supplementary binaries would then be provided by each JVM package. But then one could have set say OpenJDK7 but still have this jmc binary comming from Oracle 8. This would be inconsistent.
Don't take me wrong: I am not trying to invalidate your solution at all cost. I'm really considering including these links to the package if we happen to find a nice solution but I would just like to show you that there are a lot of complications that need to be addressed here.
[0] https://github.com/galaux/java-meta/blob/heftig_way/PKGBUILD
Maybe it's better to go back and reconsider this symlink approach. Say, we simply ship a /etc/profile.d/jre.sh wherein we add a valid jre path to PATH. We should not have to consider unsupported jre/jdk packages, but merely check for known supported pathes in jre.sh, one by one starting from e.g. the latest version, and add the first present on the filesystem to PATH. The user can nevertheless choose explicitly by editing jre.sh, or set PATH temporarily.
This is not much worse than the current interface anyway -- the symlink /usr/lib/jvm/default is set by the first JVM package only, if the user wants to change the "default" path, he will have to run `archlinux-java set ...` as root, which is not much different from editing /etc/profile.d/jre.sh by hand.
EDIT: I'm proposing removing archinux-java and java-common-wrapper entirely from the java-common package, as well as removing the call to archlinux-java from the install scriptlets of the jre/jdk packages. For anyone who wants to use multiple versions of java environments, simply modify your PATH (in /etc/profile.d/jre.sh if you want it permanent). What java-common can do as a little extra "dynamic" help is something like this, in jre.sh:
# Add a valid JVM bin path to PATH
if [ -d "/usr/lib/jvm/java-8-openjdk/jre/bin" ]; then
PATH=$PATH:"/usr/lib/jvm/java-8-openjdk/jre/bin"
elif [ -d "/usr/lib/jvm/java-7-openjdk/jre/bin" ]; then
PATH=$PATH:"/usr/lib/jvm/java-7-openjdk/jre/bin"
fi
# Enable this for non-reparenting window managers
#export _JAVA_AWT_WM_NONREPARENTING=1
Add more valid paths in the same fashion, to support some more jre packages. Any comments?
Instead of setting it by hand in jre.sh as you suggest, I could stick with PATH:$PATH:/usr/lib/jvm/default/bin and "/usr/lib/jvm/default" be set by archlinux-java. I am going to fix a package with this for test.
BUT, on the other hand, if these relevant packages which require JVM to build only need _a_ JVM, doesn't it mean they only require a limited set of binaries to be in PATH? Maybe just `java`? You know the answer better than I. Following this line of thought, maybe java-common can ship a symlink /usr/bin/java -> /usr/lib/jvm/default/bin/java for example?
Alternatively, can't you append /usr/lib/jvm/default/bin to PATH in makepkg.conf on the buld machine?
EDIT: I think it's a good idea take perl as an analogy here. For example, some packages require `pod2man` to build man pages, but pod2man is in /usr/bin/core_perl/ -- which is only appended to PATH in /etc/profile.d/perlbin.sh. This is basically the same situation with jre.sh, except that perl is part of the base group, so you can safely expect it to be installed permanently on the build machine.
Inspired by what you described, I came up with this version [0]. Instead of only shipping a "java" link, I went for the intersection of binaries between OpenJDK and Oracle 7 and 8. I had to rename "java-common" to "java-runtime-headless-common" and create a "java-environment-common". The first one ships a "PATH=$PATH:/usr/lib/jvm/default/bin" to make extra binaries available on the next "source" of profile files. Also the java-wrapper script is abandonned as it brings more troubles than it solves.
These packages are available here [1].
[0] https://github.com/galaux/java-common
[1] http://pkgbuild.com/~guillaume/repos/jdk/x86_64/
Have you considered putting /usr/lib/jvm/default{-runtime} in the package as well? They can be empty regular files, or symlinks to /dev/null or to a (possibly non-existent) default Java directory; shouldn't have any drawback, right?
https://github.com/galaux/java-common/commit/f4c7b53e90ed167bbd13fe1b1fde4eed12618152
Either:
pacman -Sy --force --asdeps java-runtime-headless-common java-environment-common
archlinux-java fix
Or
before upgrading:
archlinux-java unset
then:
pacman -Syu
I see 3 other users voted for this bug: I would love to see all your feedback on testing this.
[0] http://pkgbuild.com/~guillaume/repos/jdk/