Note: This is a public test instance of Red Hat Bugzilla. The data contained within is a snapshot of the live data so any changes you make will not be reflected in the production Bugzilla. Email is disabled so feel free to test any aspect of the site that you want. File any problems you find or give feedback at bugzilla.redhat.com.
Bug 665576
Summary: | "build-classpath swt" fails on 64bit | |||
---|---|---|---|---|
Product: | [Fedora] Fedora | Reporter: | Hicham HAOUARI <hicham.haouari> | |
Component: | jpackage-utils | Assignee: | Deepak Bhole <dbhole> | |
Status: | CLOSED RAWHIDE | QA Contact: | Fedora Extras Quality Assurance <extras-qa> | |
Severity: | medium | Docs Contact: | ||
Priority: | low | |||
Version: | 14 | CC: | akurtako, alee, aph, awnuk, dbhole, dwalluck, jdennis, mat.booth, mharmsen, nicolas.mailhot, overholt, pingou, pmatilai, sochotni, ville.skytta | |
Target Milestone: | --- | |||
Target Release: | --- | |||
Hardware: | Unspecified | |||
OS: | Unspecified | |||
Whiteboard: | ||||
Fixed In Version: | Doc Type: | Bug Fix | ||
Doc Text: | Story Points: | --- | ||
Clone Of: | ||||
: | 734590 (view as bug list) | Environment: | ||
Last Closed: | 2011-10-07 14:24:33 UTC | Type: | --- | |
Regression: | --- | Mount Type: | --- | |
Documentation: | --- | CRM: | ||
Verified Versions: | Category: | --- | ||
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | ||
Cloudforms Team: | --- | Target Upstream Version: | ||
Embargoed: | ||||
Bug Depends On: | ||||
Bug Blocks: | 665426, 734590 |
Description
Hicham HAOUARI
2010-12-24 23:12:32 UTC
In macros.jpackage (in jpackage-utils' source), there exists these lines: # Directory where arch-specific (JNI) version-independent jars are installed. # # By extension: # %{_jnidir}-ext: # - version dependent jars # %{_jnidir}-x.y.z: # - jars for Java standard x.y.z (usually symlinks to %{_jnidir}-ext) # To simplify things only %{_jnidir} is defined. # %_jnidir %{_prefix}/lib/java The thing that's confusing me is the same directory supposedly used for multiple architecture-dependent JARs of the same name. Is this what's intended? Nicolas/Ville/David, can you lend some expertise here? Thanks. It seems to me that instead of: %_jnidir %{_prefix}/lib/java it should be: %_jnidir %{_libdir}/java Otherwise build-classpath/find_jar are looking in the wrong place. Using %{_libdir} is not enough since 32 bit JVMs and packages may exist on a 64 bit system, in which case they will not be seen. I've never quite understood why it's done the way it is so I'm afraid I don't have any expertise to share here. Anyway it doesn't matter where jpackage-utils is built, jnidir never ends up containing %{_libdir}, it's always %{_prefix}/lib. But just guessing, this could be a relic from times when there was no 64-bit java plugin and/or web start and thus installing 32-bit VMs on 64-bit boxes was a more common real world scenario. If you ask me, support for that (c|sh)hould be purged - there are no ix86 JVMs in the x86_64 repo anyway. To actually work on a multilib system _jnidir should be defined as %{_libdir}/java However the original build-classpath scripts were written on a 32 bit system with no access to 64 bitness (was in infancy at the time). They do not look in lib64 at all. Rather than fix it in the scripts, jnidir was re-defined as %{_prefix}/lib/java when the first 64 bit users complained. I don't see how it can work on a mixed (32+64 system) So if you want to fix it, you need to add some shell logic in jpackage-utils to look in lib64 too if it's present, and then redefine _jnidir to its original value. (In reply to comment #5) > So if you want to fix it, you need to add some shell logic in jpackage-utils to > look in lib64 too if it's present, and then redefine _jnidir to its original > value. I suppose a simpler alternative would be to just use %{_libdir} in /etc/rpm/macros.jpackage where appropriate, and change /etc/java/java.conf to have JNI_LIBDIR=$(rpm --eval %{_jnidir}) and JVM_ROOT=$(rpm --eval %{_jvmdir}). But that'd require a lot of rebuilds, but would also result in cleaner/simpler end result. This is just from quickly peeking into the scripts, not thought much at all. (In reply to comment #6) > (In reply to comment #5) > > So if you want to fix it, you need to add some shell logic in jpackage-utils to > > look in lib64 too if it's present, and then redefine _jnidir to its original > > value. > > I suppose a simpler alternative would be to just use %{_libdir} in > /etc/rpm/macros.jpackage where appropriate, and change /etc/java/java.conf to > have JNI_LIBDIR=$(rpm --eval %{_jnidir}) and JVM_ROOT=$(rpm --eval %{_jvmdir}). > But that'd require a lot of rebuilds, but would also result in cleaner/simpler > end result. This is just from quickly peeking into the scripts, not thought > much at all. Doesn't seem like all packages follow a hard and fast rule: yum install '/usr/lib64/java/*' only brings in eclipse-swt. yum install '/usr/lib/java/*' OTOH brings in a few more: Installing: brlapi-java x86_64 0.5.5-3.fc14 fedora 27 k jffi x86_64 0.6.5-4.fc14 fedora 194 k osutil x86_64 1.3.1-3.fc14 fedora 25 k pki-symkey x86_64 1.3.2-4.fc14 fedora 31 k All of the above are arch specific, yet install in /usr/lib/java even on 64-bit. Yes, that's what I meant by "that'd require a lot of rebuilds". I believe there are three alternative ways to fix this, in no particular order: A) Tweak jpackage-utils to look first into lib64 dirs, then fall back to lib, keep macros as is (this if I understood right was what Nicolas suggested). B) Bite the bullet, make the dirs lib64 on x86_64 in macros etc, fix/rebuild what needs fixing (this is what I suggested). C) Keep jpackage-utils as is, but install swt stuff to "lib" (not lib64) dirs no matter what the arch is. My preference would be B, and I'll shut up now :) B is the correct solution mid-term, but the jpackage-utils scripts probably need to fall back to lib during the transition unless someone wants to handle a mass rebuild. So I suggested the same thing as you, but with a safety fallback. As Deepak pointed out in comment #3, the %{_libdir} macro should fix building, but during runtime there would need to be a function in the scripts to set the libdir (-Djava.library.dir) based on the JVM arch, not the host arch. That should be java.library.path in comment #10. Builds that required native libs typically set this themselves in the %{_bindir} script or a config file in %{_sysconfdir}, but I doubt it took into account that scenario. We talked about this during SIG meeting and we all agreed that B option is OK. We are doing this switch really early so we have plenty of time to fix breakages in F16 rawhide. So you can go ahead with this. FYI: $ repoquery --repoid=rawhide --whatprovides /usr/lib/java/\* tritonus-0:0.3.7-0.12.20101108cvs.fc15.x86_64 nuxwdog-client-java-0:1.0.1-2.fc15.x86_64 pki-symkey-0:9.0.3-2.fc15.x86_64 jss-0:4.2.6-14.fc15.x86_64 osutil-0:2.0.1-2.fc15.x86_64 brlapi-java-0:0.5.5-4.fc15.x86_64 symkey-0:1.3.0-4.fc13.x86_64 jffi-0:1.0.2-1.fc15.x86_64 pki-symkey-0:1.3.2-5.fc15.x86_64 My 2 cents -- although it sounds as if you guys have already decided this - *sigh*! I believe that what is being missed here is that first and foremost, ONLY Java applications use JNI, and Java applications are ARCHITECTURE INDEPENDENT! Our application is one of the biggest users of JNI libraries -- in fact, members of my team own the following: nuxwdog-client-java-0:1.0.1-2.fc15.x86_64 pki-symkey-0:9.0.3-2.fc15.x86_64 jss-0:4.2.6-15.fc15.x86_64 osutil-0:2.0.1-2.fc15.x86_64 NOTE: symkey-0:1.3.0-4.fc13.x86_64 and pki-symkey-0:1.3.2-5.fc15.x86_64 are no longer valid (or soon won't be). Being a Java application which utilizes JNI libraries basically means that requests travel through a JNI jar file to its associated native .so portion (32-bit or 64-bit) and back to the Java application -- Java drives this, NOT the underlying 32-bit/64-bit libraries. In Linux, the way our code is constructed in our JNI libraries is to ALWAYS use CLASSPATHS which look for a JNI JAR file under /usr/lib/java (e. g. - ALWAYS specified by '%_jnidir' in the spec files). Each JNI jar file contains the logic to look first for an associated 64-bit library under /usr/lib64/<JNI name> followed by looking for an associated 32-bit library under /usr/lib/<JNI name> (to allow for a 32-bit version of the product to be installed on a 64-bit platform). The only obvious issue is that one cannot have BOTH 32-bit and 64-bit versions of the Java product installed on the system at the same time -- something that has never been a requirement for our product -- and seems highly questionable as to why one would want to have both 32-bit and 64-bit versions of the same architecture-independent Java application residing on the platform simultaneously. It is my belief that our current packaging solution (already applied to osutil, pki-symkey, and jss) works quite well without any changes; it applies the Fedora rule of placing application-specific libraries (in this case, JNI libraries) under their own private directory (e. g. - /usr/lib/jss and /usr/lib64/jss): 32-bit: /usr/lib/java/jss4.jar -> /usr/lib/jss/jss4.jar /usr/lib/jss/jss4-4.2.6.jar /usr/lib/jss/jss4.jar -> jss4-4.2.6.jar /usr/lib/jss/libjss4.so /usr/lib/java/osutil.jar -> /usr/lib/osutil/osutil.jar /usr/lib/osutil /usr/lib/osutil/libosutil.so /usr/lib/osutil/osutil-2.0.1.jar /usr/lib/osutil/osutil.jar -> osutil-2.0.1.jar /usr/lib/java/symkey.jar -> /usr/lib/symkey/symkey.jar /usr/lib/symkey /usr/lib/symkey/libsymkey.so /usr/lib/symkey/symkey-9.0.3.jar /usr/lib/symkey/symkey.jar -> symkey-9.0.3.jar 64-bit: /usr/lib/java/jss4.jar -> /usr/lib64/jss/jss4.jar /usr/lib64/jss/jss4-4.2.6.jar /usr/lib64/jss/jss4.jar -> jss4-4.2.6.jar /usr/lib64/jss/libjss4.so /usr/lib/java/osutil.jar -> /usr/lib64/osutil/osutil.jar /usr/lib64/osutil /usr/lib64/osutil/libosutil.so /usr/lib64/osutil/osutil-2.0.1.jar /usr/lib64/osutil/osutil.jar -> osutil-2.0.1.jar /usr/lib/java/symkey.jar -> /usr/lib64/symkey/symkey.jar /usr/lib64/symkey /usr/lib64/symkey/libsymkey.so /usr/lib64/symkey/symkey-9.0.3.jar /usr/lib64/symkey/symkey.jar -> symkey-9.0.3.jar There are 4 different issues at play and I'm afraid they haven't been clearly separated in the existing discussion. They are: 1) How the jni lib is built for a given arch 2) Where the arch specific jni is installed 3) How the jni lib is loaded 4) How class paths are resolved Let's also declare a goal of fully supporting multilib and that multilib support should follow the existing multilib processes and conventions. What does multilib mean for Java applications which are normally thought of as architecture independent? It is defined by the JVM which loads the classes. There may be both a 32-bit and 64-bit JVM present on the system. The following is critical, the selection of the JVM is independent. The build/package/install/load mechanisms must be able to correctly handle either a 32-bit JVM or a 64-bit JVM. I do not subscribe to the assertion that a 32-bit JVM on a 64-bit system need not be supported nor that one should not be able to switch between 32-bit and 64-bit JVM's at will. The ability to choose between 32-bit and 64-bit JVM's is a fundamental property of any multilib system, you're supposed to be able to make the choice. Issue 1: The jni lib should be built like any other arch specific rpm component. In practice this will mean there will be both a x86 and x86_64 package (ppc and ppc64, so forth). %{_libdir} should be utilized during building just as any other arch specific build. Issue 2: Because we've set ourselves the goal of supporting multilib the arch specific package needs to install into a matching arch specific library. Utilizing %{_libdir}/java would make sense, it keeps 32-bit and 64-bit libraries distinct and follows existing multilib guidelines. Issue 3: This is the most interesting of the 4 issues. The version of the jni lib which is loaded MUST match the JVM. Recall it's the JVM which determines whether a 32-bit or 64-bit JNI library should be loaded, 32-bit JVM's need 32-bit JNI's and 64-bit JVM's need 64-bit JNI's. In a perfect world the JVM would select the correct JNI bitness to load. One might hope System.loadLibrary() could perform this for us but the designers of Java and the implementers of JVM's did not anticipate this. Plus System.loadLibrary() does not provide the flexibility to install libraries outside of a system canonical location. For instance app specific JNI's might wish to follow FHS guidelines and install in app specific directories. Since the JNI to be loaded is a function of the JVM and System.loadLibrary() isn't an option we're forced to utilize System.load(). The pure Java component will need to determine the bitness of the JVM. There would appear to be no direct Java query for this, but fortunately System.getProperty("os.arch") returns the arch of the JVM not the OS, which because it's JVM specific meets our needs. Thus the pure Java component will need to call System.getProperty("os.arch") and modify it's library path accordingly. But what is the library path? At this point I do not know if the java.library.path property is reliable or whether one should just follow the packaging conventions of the Linux distribution, in which case the pure Java could would need to perform some other environmental property query. Or the library path could be hardcoded into the pure Java code as the PKI classes currently do. Or the path could be substituted during the build step, I think this is probably the preferred and most robust approach. As an aside it's too bad that not all Linux distributions follow the same library path conventions. Issue 4: Classpath resolution is what began this whole discussion. Classpaths are independent of the JVM. Thus classpaths cannot be sensitive to the arch of a JNI library. build-classpath is not at fault. To my mind the problem is the bundling of the arch independent pure Java component of a JNI jar in the same location as the arch specific JNI library. Why? The answer is described in Issue 3, it's the pure Java code which queries the JVM it's running it to determine which arch specific JNI library to load via System.load(). If the arch independent pure Java is located in the same class path locations then build-classpath is not going to fail. But what happens when an arch specific JNI library is not installed and thus not available for loading via System.load()? It should throw an exception just like everything else. Recall that passing CLASSPATH to a JVM which does not contain a required class is a common problem, there is nothing which says the link requirements are guaranteed to be resolvable prior to execution, thus we have not violated any assumptions. Summary: Use %{_libdir}/java as %{jnidir} for building. Use System.load() to select the jnidir matched to the JVM. Install the Java component of a JNI library in the standard Java classpath instead of bundling with the arch specific jni .so Additional information: My comments in Comment 13 above were based upon the following document: * http://fedoraproject.org/wiki/Packaging/Java#Packaging_JAR_files_that_use_JNI Specifically, the sentence "JAR files that require JNI shared objects MUST be installed in %{_libdir}/%{name}." NOTE: What may have not been clear was that the JAR file components of both the 32-bit and 64-bit versions of each JNI package are identical. The sentence "If the JNI-using code calls System.loadLibrary you'll have to patch it to use System.load, passing it the full path to the dynamic shared object." is currently addressed thusly (using 'osutil' as an example): static boolean tryLoad( String filename ) { try { System.load( filename ); } catch( Exception e ) { return false; } catch( UnsatisfiedLinkError e ) { return false; } return true; } // Load native library static { boolean mNativeLibrariesLoaded = false; String os = System.getProperty( "os.name" ); if( ( os.equals( "Linux" ) ) ) { // Check for 64-bit library availability // prior to 32-bit library availability. mNativeLibrariesLoaded = tryLoad( "/usr/lib64/osutil/libosutil.so" ); if( mNativeLibrariesLoaded ) { System.out.println( "64-bit osutil library loaded" ); } else { // REMINDER: May be trying to run a 32-bit app // on 64-bit platform. mNativeLibrariesLoaded = tryLoad( "/usr/lib/osutil/libosutil.so" ); if( mNativeLibrariesLoaded ) { System.out.println( "32-bit osutil library loaded"); } else { System.out.println( "FAILED loading osutil library!"); System.exit( -1 ); } } } else { try { System.loadLibrary( "osutil" ); System.out.println( "osutil library loaded" ); mNativeLibrariesLoaded = true; } catch( Throwable t ) { // This is bad news, the program is doomed at this point t.printStackTrace(); } } } We deviated from Fedora instructions only insomuch as that for all of the wrapper scripts within our server that use CLASSPATH, we simply included /usr/lib/java (as defined by %_jnidir) which contains the appropriate symlink rather than the sentence "If the package installs a wrapper script you'll need to manually add %{_libdir}/%{name}/<jar filename> to CLASSPATH. If you are depending on a JNI-using JAR file, you'll need to add it manually -- build-classpath will not find it.". ============================================================================== In order to comply with what Fedora already suggests, what is being proposed by the bug, what is proposed in Comment #14, and still trying to maintain minimal disruption to the existing packages, I propose the following: Verifying "os.arch" from Comment #14 on a 64-bit VM: class WhatOS { public static void main( String args[] ) { System.out.println( System.getProperty("os.name") ); System.out.println( System.getProperty("os.version") ); System.out.println( System.getProperty("os.arch") ); } } # /usr/lib/jvm/jre-1.6.0-openjdk.x86_64/bin/java WhatOS Linux 2.6.38-0.rc4.git0.2.fc15.x86_64 amd64 # /usr/lib/jvm/jre-1.6.0-openjdk/bin/java WhatOS Linux 2.6.38-0.rc4.git0.2.fc15.x86_64 i386 would imply changing existing JNI code to something like this (again, using 'osutil' as an example): static boolean tryLoad( String filename ) { try { System.load( filename ); } catch( Exception e ) { return false; } catch( UnsatisfiedLinkError e ) { return false; } return true; } // Load native library static { boolean mNativeLibrariesLoaded = false; String os = System.getProperty( "os.name" ); String jre_arch = System.getProperty( "os.arch" ); String load_lib = null; if( ( os.equals( "Linux" ) ) ) { if( ( jre_arch.equals( "x86_64" ) ) || ( jre_arch.equals( "amd64" ) ) ) { // Check for 64-bit library availability load_lib = "64-bit"; mNativeLibrariesLoaded = tryLoad( "/usr/lib64/osutil/libosutil.so" ); } else if( ( jre_arch.equals( "i386" ) ) || ( jre_arch.equals( "i486" ) ) || ( jre_arch.equals( "i586" ) ) || ( jre_arch.equals( "i686" ) ) ) { // Check for 32-bit library availability load_lib = "32-bit"; mNativeLibrariesLoaded = tryLoad( "/usr/lib/osutil/libosutil.so" ); } if( mNativeLibrariesLoaded ) { System.out.println( load_lib + " osutil library loaded" ); } else { System.out.println( "FAILED loading " + load_lib + " osutil library!"); System.exit( -1 ); } } else { try { System.loadLibrary( "osutil" ); System.out.println( "osutil library loaded" ); mNativeLibrariesLoaded = true; } catch( Throwable t ) { // This is bad news, the program is doomed at this point t.printStackTrace(); } } } Similar code would need to be applied to 'pki-symkey', 'jss', and 'nuxwdog-client'. The corresponding 32-bit and 64-bit 'osutil' RPMS would then be re-packaged to contain: 32-bit: /usr/lib/java/osutil.jar -> /usr/lib/osutil/osutil.jar /usr/lib/osutil/ /usr/lib/osutil/libosutil.so /usr/lib/osutil/osutil-2.0.1.jar /usr/lib/osutil/osutil.jar -> osutil-2.0.1.jar /usr/share/doc/osutil-2.0.1/ /usr/share/doc/osutil-2.0.1/LICENSE 64-bit: /usr/lib64/java/osutil.jar -> /usr/lib64/osutil/osutil.jar /usr/lib64/osutil/ /usr/lib64/osutil/libosutil.so /usr/lib64/osutil/osutil-2.0.1.jar /usr/lib64/osutil/osutil.jar -> osutil-2.0.1.jar /usr/share/doc/osutil-2.0.1/ /usr/share/doc/osutil-2.0.1/LICENSE IMPORTANT: Within Dogtag, wrappers using CLASSPATH would need to be changed to determine which JRE architecture was being invoked PRIOR to setting CLASSPATH, as one would need to distinguish between "/usr/lib/java" and "/usr/lib64/java" in the CLASSPATH. CAVEAT: While this would address being able to simultaneously install and distinguish between 32-bit and 64-bit versions of JNI (although both packages still contain the identical directory "/usr/share/doc/osutil-2.0.1" and the file "/usr/share/doc/osutil-2.0.1/LICENSE"?), it is highly unlikely that Dogtag could be simultaneously installed as both a 32-bit application and a 64-bit application, due to other portions of the server never having been required to be simultaneously multi-arch aware. The "revised" code in Comment 15 above still needs appropriate error handling for platforms that are not supported in Linux. While it is certainly possible to write add code to jni jars so they call different libs depending on the bit-ness of the jvm they're executed in, it will play major havoc rpm dependencies-side. I honestly can not see how such a scenario can work safely without requiring both 32 and 64 bit libs in the rpm containing the jar file, which will annoy users tremendously. It would be much easier and safer to generate one 32 bit and one 64 bit jni jar, as it's how the rest of the platform work. Please do not forget the result needs to be deployed before adding code to support a mode others part of the stack can not work with Adding Seth and Pati to have an informed opinion on whether it is possible to express sanely "foo depends on arch-lib, where arch depends on the arch of the jvm it's invoqued from" Though thinking a bit more about it, it may work if you create two arched-rpms, containing the same file in the same location but with different rpm architectures and depending on different libraries (good luck to whoever will write the spec template for this) But at this point, is it really worth it to multiplex the jni glue in a single file? re comment #17 and comment #19 Couldn't the packaging issue be simply solved with virtual provides/requires? The noarch pure java package requires a package which provides the virtual jni lib. Each arch specific jni lib package offers a virtual provides for the jni lib. Additional information: All JNI packages mentioned are "architecture-specific". JNI consists of two parts: * an architecture-independent JAR file required by Java, * an architecture-dependent shared object. Since JNI was first placed into RPMS spanning multiple releases of Dogtag and RHCS, separate architecture-dependent RPMS have always been issued which contained an architecture-independent JAR, an architecture-dependent shared object, and an architecture-independent LICENSE file. Both the LICENSE and the JAR were identical across all RPMS. JNI is convenience interface allowing to reuse native code, providing performance or functionally not available in Java, so why impose artificial bit-rules restricting this convenience. Most Java users are annoyed just by facing necessity of using JNI, since it comes with extra maintenance hassles. In many cases they face limited choices due to the functionality they need to provide. Those limited choices may force them to mix native code types. Restricting their limited options by imposing additional bit-rules is not going to help them. re comment #22 Andrew I didn't follow your point, could you rephrase it please? FWIW, we're trying to simplify JNI usage for users and allow JNI to be more flexible. It complicates the packaging a bit, but not the user experience. What inconvenient "artificial" bit-rules are being imposed? (In reply to comment #23) JNI has its own limitations and I would like to avoid imposing new ones. If JNI allows me to use 32 and 64 bit native libraries, I would like to be able to use either of them or both of them if I need to. We should not add restrictions based on JVM architecture other than the ones set by JVM itself. re comment #24 > If JNI allows me to use 32 and 64 bit native libraries, I would like > to be able to use either of them or both of them if I need to. Good that's my goal too. > We should not add restrictions based on JVM architecture other than > the ones set by JVM itself. That's where you lost me. We're not adding any new restrictions. It's a fact of life 32-bit JVM's can only load 32-bit JNI libraries and 64-bit JVM's can only load 64-bit libraries. 32-bit JNI libraries can only link with 32-bit libraries, 64-bit JNI libraries can only link with 64-bit libraries. Which JNI you load (32-bit vs. 64-bit) is function of the JVM. (In reply to comment #25) > > We should not add restrictions based on JVM architecture other than > > the ones set by JVM itself. > > That's where you lost me. We're not adding any new restrictions. It's a fact of > life 32-bit JVM's can only load 32-bit JNI libraries and 64-bit JVM's can only > load 64-bit libraries. 32-bit JNI libraries can only link with 32-bit > libraries, 64-bit JNI libraries can only link with 64-bit libraries. > > Which JNI you load (32-bit vs. 64-bit) is function of the JVM. Sorry for confusion. Since JNI documentation is bit vague, I falsely draw conclusions based on my Smalltalk experience. That other VM was able to access 64-bit and 32-bit libraries at the same time. Another proposal: Our current model is detailed in Comment #13 which we believe basically conforms to existing Fedora JNI requirements detailed in http://fedoraproject.org/wiki/Packaging/Java#Packaging_JAR_files_that_use_JNI (but does not provide for simultaneous multi-arch capability): * osutil-2.0.1-2.fc15.i686.rpm /usr/lib/java/osutil.jar -> /usr/lib/osutil/osutil.jar /usr/lib/osutil /usr/lib/osutil/libosutil.so /usr/lib/osutil/osutil-2.0.1.jar /usr/lib/osutil/osutil.jar -> osutil-2.0.1.jar /usr/share/doc/osutil-2.0.1 /usr/share/doc/osutil-2.0.1/LICENSE * osutil-2.0.1-2.fc15.x86_64.rpm /usr/lib/java/osutil.jar -> /usr/lib64/osutil/osutil.jar /usr/lib64/osutil /usr/lib64/osutil/libosutil.so /usr/lib64/osutil/osutil-2.0.1.jar /usr/lib64/osutil/osutil.jar -> osutil-2.0.1.jar /usr/share/doc/osutil-2.0.1 /usr/share/doc/osutil-2.0.1/LICENSE My initial proposal was outlined in Comment #15, and would produce the following two RPMS which would, for the most part, satisfy the desire for simultaneous multi-arch RPMS (except for potentially the LICENSE issue): * osutil-2.0.1-2.fc15.i686.rpm /usr/lib/java/osutil.jar -> /usr/lib/osutil/osutil.jar /usr/lib/osutil/ /usr/lib/osutil/libosutil.so /usr/lib/osutil/osutil-2.0.1.jar /usr/lib/osutil/osutil.jar -> osutil-2.0.1.jar /usr/share/doc/osutil-2.0.1/ /usr/share/doc/osutil-2.0.1/LICENSE * osutil-2.0.1-2.fc15.x86_64.rpm /usr/lib64/java/osutil.jar -> /usr/lib64/osutil/osutil.jar /usr/lib64/osutil/ /usr/lib64/osutil/libosutil.so /usr/lib64/osutil/osutil-2.0.1.jar /usr/lib64/osutil/osutil.jar -> osutil-2.0.1.jar /usr/share/doc/osutil-2.0.1/ /usr/share/doc/osutil-2.0.1/LICENSE If we are allowed to change the existing Fedora requirement of "JAR files that require JNI shared objects MUST be installed in %{_libdir}/%{name}.", we could separate packages to allow for simultaneous multi-arch without compromising existing solutions which have effectively utilized "%{_jnidir}": * osutil-2.0.1-2.fc15.noarch.rpm /usr/lib/java/osutil-2.0.1.jar /usr/lib/java/osutil.jar -> osutil-2.0.1.jar /usr/share/doc/osutil-2.0.1/ /usr/share/doc/osutil-2.0.1/LICENSE * osutil-jni-native-2.0.1-2.fc15.i686.rpm /usr/lib/osutil/ /usr/lib/osutil/libosutil.so * osutil-jni-native-2.0.1-2.fc15.x86_64.rpm /usr/lib64/osutil/ /usr/lib64/osutil/libosutil.so This proposal basically requires: * a change to the source code as detailed in Comment #15 above (with the necessary error handling), * changes to the spec file which separates the packages as detailed above: * osutil.spec . . . BuildRequires: cmake BuildRequires: java-devel >= 1:1.6.0 BuildRequires: jpackage-utils BuildRequires: nspr-devel BuildRequires: nss-devel BuildRequires: pkgconfig . . . %package -n osutil BuildArch: noarch Requires: java >= 1:1.6.0 Requires: jpackage-utils %ifarch i686 Requires: osutil-jni-native.i686 %endif %ifarch x86_64 Requires: osutil-jni-native.i686 Requires: osutil-jni-native.x86_64 %endif . . . %package -n osutil-jni-native Requires: nss . . . %files -n osutil %defattr(-,root,root,-) %doc LICENSE %{_jnidir}/osutil.jar . . . %files -n osutil-jni-native %{_libdir}/osutil/ (In reply to comment #27) > If we are allowed to change the existing Fedora requirement of "JAR files that > require JNI shared objects MUST be installed in %{_libdir}/%{name}.", we could > separate packages to allow for simultaneous multi-arch without compromising > existing solutions which have effectively utilized "%{_jnidir}": > > * osutil-2.0.1-2.fc15.noarch.rpm > /usr/lib/java/osutil-2.0.1.jar > /usr/lib/java/osutil.jar -> osutil-2.0.1.jar Is there a technical problem why this couldn't be placed in /usr/share/java/osutil.jar ? Note that current guidelines don't have versioned jar files (osutil-2.0.1.jar shouldn't exist). As for requiring both i686 and x86_64 libraries on x86_64 system. I don't particularly like this (unnecessary dependency if someone has x86_64 only system with no 32bit java), I don't really have a better solution. Also please don't consider JNI packaging documentation binding at all at this time. Consider this a place to discuss how to fix it properly. If we come up with a good solution, we are going to update the guidelines to reflect this change. We knew JNI guidelines were in need of an update badly for some time, but there were not enough people who really understood what was going on (I certainly didn't). It seems to me you are those people so let's fix it up once and for all :-) (In reply to comment #20) > re comment #17 and comment #19 > > Couldn't the packaging issue be simply solved with virtual provides/requires? > > The noarch pure java package requires a package which provides the virtual jni > lib. Not really because you need the bit-ness of the jni lib and of the jvm to match One can not really express in a packaging system needs (64 bit jvm and 64 bit lib) or (32 bit jvm and 32 bit lib) The only simple robust solution IMHO is a 32 bit package with the jni jar that requires (32 bit jvm and 32 bit lib), and another 64 bit package that requires (64 bit jvm and 64 bit lib) That may seem simplistic but if rpm/deb/whatever can handle very complex systems, it's because the dependency rules have been simplified to the point it is possible to compute them automatically. The situation on windows is very different. Here you can do all sorts of if-defing in the installation package, but the result is too complex to be integrated system-wide. re comment #29 > The only simple robust solution IMHO is a 32 bit package with the jni jar that > requires (32 bit jvm and 32 bit lib), and another 64 bit package that requires > (64 bit jvm and 64 bit lib) Yes that works and is the most robust. It's OK for the 32-bit and 64-bit versions of the rpm to contain the same noarch files as long as they are identical. The only minor issue in your proposal is that java is a virtual provides. This makes sense because there are many packages which provide java (not only different vendors/implementations but also different bitness within a vendor/implementation). We would probably need to augment the java virtual provides in the java* packages with a virtual provides for the bitness, maybe something like jre-32bit and jre-64bit. Then the jni 32-bit package would require jre-32bit and the 64-bit jni package would require jre-64bit. A number of different rpms could provide either. One thing I've ignored in the discussion so far is whether jni .so's have a dependency on the specific jvm loading it. In other words can a Sun jvm and an OpenJDK jvm both load the same jni.so? (In reply to comment #30) > re comment #29 > > > The only simple robust solution IMHO is a 32 bit package with the jni jar that > > requires (32 bit jvm and 32 bit lib), and another 64 bit package that requires > > (64 bit jvm and 64 bit lib) > > Yes that works and is the most robust. It's OK for the 32-bit and 64-bit > versions of the rpm to contain the same noarch files as long as they are > identical. There might be a problem however if you try to automate jni dependency extraction later (now that dependency extractors have been split from rpm itself) re comment #31 I'm at a loss for how one would handle jni depedencies in all combinations, I don't think the rpm dependency model is rich enough. However it should work in the default cases. In other words each multi-arch platform has a defined arch preference, as long as the dependencies are evaluated in the context of the preferred default arch I believe everything works out. If you start installing non-preferred arches for jni components then yum/rpm isn't going to be able to determine the dependency set, you'll have to manually install some packages. I just don't see a way around this if unless you want to include both 32-bit and 64-bit .so in one package (but that's in conflict with the existing packaging model and an earlier goal, plus I don't even know how you would do such a package build). The essential problem is that the jvm is a transitive run time dependency, rpm has no facility for determining dependencies which are only known at run time. I guess the best way to sum this up is that Java JNI is a weird corner case not supported by the existing models. If you want to be brutally honest I think it would be fair to say multi-arch on Fedora is a bit of a hack which only works by virtue of adopted conventions and special case processing introduced into yum and rpm. We've been forced to use a packaging system which never was designed to support multi-arch. This explanation from Bill Nottingham is an interesting read: http://lists.fedoraproject.org/pipermail/devel/2010-January/129725.html (In reply to comment #28) > Is there a technical problem why this couldn't be placed in > /usr/share/java/osutil.jar ? > While there may be no "technical" reason, it has been common and traditional for us to place the JAR portion of a JNI into /usr/lib/java (%{_jnidir}) to distinguish JNI JARS which require a native .so component versus Pure Java JARS that require no .so component (/usr/share/java). For previous products, we delivered these same JNI JARS to Solaris systems using the same separation mechanism (/usr/lib/java and /usr/share/java). By maintaining this separate location, one can always easily understand that they are looking at a JNI JAR versus Pure Java JAR. > Note that current guidelines don't have versioned jar files (osutil-2.0.1.jar > shouldn't exist). > While guidelines may not exist for this for JNI JARS, once again, it is commmon usage for Pure Java JARS located under /usr/share/java to use this convention, and consequently, we mimic this convention for JNI JARS. > As for requiring both i686 and x86_64 libraries on x86_64 system. I don't > particularly like this (unnecessary dependency if someone has x86_64 only > system with no 32bit java), I don't really have a better solution. > This was merely an attempt at addressing the following portion of jdennis comment #14: > Let's also declare a goal of fully supporting multilib and that > multilib support should follow the existing multilib processes and > conventions. What does multilib mean for Java applications which are > normally thought of as architecture independent? It is defined by the > JVM which loads the classes. There may be both a 32-bit and 64-bit JVM > present on the system. The following is critical, the selection of the > JVM is independent. The build/package/install/load mechanisms must be > able to correctly handle either a 32-bit JVM or a 64-bit JVM. > I do not subscribe to the assertion that a 32-bit JVM on a 64-bit > system need not be supported nor that one should not be able to switch > between 32-bit and 64-bit JVM's at will. The ability to choose between > 32-bit and 64-bit JVM's is a fundamental property of any multilib > system, you're supposed to be able to make the choice. (In reply to comment #33) > (In reply to comment #28) > > Is there a technical problem why this couldn't be placed in > > /usr/share/java/osutil.jar ? > > > > While there may be no "technical" reason, it has been common and traditional > for us to place the JAR portion of a JNI into /usr/lib/java (%{_jnidir}) to > distinguish JNI JARS which require a native .so component versus Pure Java JARS > that require no .so component (/usr/share/java). For previous products, we > delivered these same JNI JARS to Solaris systems using the same separation > mechanism (/usr/lib/java and /usr/share/java). By maintaining this separate > location, one can always easily understand that they are looking at a JNI JAR > versus Pure Java JAR. OK, history and backward compatibility aside...FHS requires architecture independent files to be in /usr/share. I guess what I would like best is something like /usr/share/java-jni. Still makes it clear it's JNI, but there is nice separation between native and noarch part, plus all the jars are close. If we are already changing this, I'd like to really get it right. We are already doing major changes so I we'll have to fix packages one way or the other. > > Note that current guidelines don't have versioned jar files (osutil-2.0.1.jar > > shouldn't exist). > > > > While guidelines may not exist for this for JNI JARS, once again, it is commmon > usage for Pure Java JARS located under /usr/share/java to use this convention, > and consequently, we mimic this convention for JNI JARS. Ok, let me rephrase. We recently (~3-4 months ago) changed the guidelines so we wouldn't have to deal with versioned/unversioned symlinks etc. We only install unversioned jar files. There is no real value as far as I can see in having both. In fact it hinders performance in certain scenarios where tools are walking the filesystem tree (double the amount of work they need to do). It also makes spec files more complicated. Since jars are from rpm files we can still easily query version of each and every file. I would be against reintroducing versioned/unversioned symlinks into the mix. > > As for requiring both i686 and x86_64 libraries on x86_64 system. I don't > > particularly like this (unnecessary dependency if someone has x86_64 only > > system with no 32bit java), I don't really have a better solution. > > > > This was merely an attempt at addressing the following portion of jdennis > comment #14: Yes, I understand that and again...not really a big problem IMO. (In reply to comment #34) > > OK, history and backward compatibility aside...FHS requires architecture > independent files to be in /usr/share. I guess what I would like best is > something like /usr/share/java-jni. Still makes it clear it's JNI, but there is > nice separation between native and noarch part, plus all the jars are close. > > If we are already changing this, I'd like to really get it right. We are > already doing major changes so I we'll have to fix packages one way or the > other. > I have no problems with this as it does not complicate placing architecture-independent jars in multiple architecture-dependent locations as was previously suggested. One question -- could/should the %{_jnidir} macro be changed on Fedora 16 and later to reflect the new location (e. g. - /usr/share/java-jni), or could/should a new macro (e. g. - %{_javajnidir}) be introduced so as to not conflict with the historic use of %{_jnidir} (e. g. - on RHEL platforms)? > > Ok, let me rephrase. We recently (~3-4 months ago) changed the guidelines so we > wouldn't have to deal with versioned/unversioned symlinks etc. We only install > unversioned jar files. There is no real value as far as I can see in having > both. In fact it hinders performance in certain scenarios where tools are > walking the filesystem tree (double the amount of work they need to do). It > also makes spec files more complicated. Since jars are from rpm files we can > still easily query version of each and every file. I would be against > reintroducing versioned/unversioned symlinks into the mix. > Sorry, I was unaware that the java jar naming guidelines had been changed. Do these revised guidelines only correspond to Fedora 16 and later? (In reply to comment #30) > One thing I've ignored in the discussion so far is whether jni .so's have a > dependency on the specific jvm loading it. In other words can a Sun jvm and an > OpenJDK jvm both load the same jni.so? Maybe, because they're the same VM inside, but it would be foolish to depend on it. (In reply to comment #35) > > Ok, let me rephrase. We recently (~3-4 months ago) changed the guidelines so we > > wouldn't have to deal with versioned/unversioned symlinks etc. We only install > > unversioned jar files. There is no real value as far as I can see in having > > both. In fact it hinders performance in certain scenarios where tools are > > walking the filesystem tree (double the amount of work they need to do). It > > also makes spec files more complicated. Since jars are from rpm files we can > > still easily query version of each and every file. I would be against > > reintroducing versioned/unversioned symlinks into the mix. > > > > Sorry, I was unaware that the java jar naming guidelines had been changed. Do > these revised guidelines only correspond to Fedora 16 and later? There are packages in Fedora 15 that follow the new guidelines. It's not enforced with an iron fist, just the next time you update your packages is fine. :-) So I decided to bite the bullet and did changes that will break things I am sure: %_jnidir is now %_libdir/java %_javajnidir is new addition for noarch jars using arch-specific bits from %_jnidir build-classpath has been changed to resolve from this new directory as well. Maven is also resolving from _jnidir and _javajnidir (it didn't before). This change will break builds and in a few cases patches will need to be created to fix them. I've tested with osutil. I had to fix cmake-> - "${CMAKE_INSTALL_PREFIX}/lib/java" + "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/java" And that was it. I would be really interested how many things broke because of these changes. If we can make this work (which I believe shouldn't be that hard), we can modify our current guidelines to reflect these changes. In next 2 weeks I'll go through packages that have files in /usr/lib/java and rebuild them, and also look at packages that depend on these. I won't be around much because of holidays for next few days, so if anyone would look into it before me: great! (In reply to comment #38) > So I decided to bite the bullet and did changes that will break things I am > sure: > > %_jnidir is now %_libdir/java > %_javajnidir is new addition for noarch jars using arch-specific bits from > %_jnidir > > build-classpath has been changed to resolve from this new directory as well. > Maven is also resolving from _jnidir and _javajnidir (it didn't before). > > This change will break builds and in a few cases patches will need to be > created to fix them. I've tested with osutil. I had to fix cmake-> > - "${CMAKE_INSTALL_PREFIX}/lib/java" > + "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/java" > > And that was it. I would be really interested how many things broke because of > these changes. > > If we can make this work (which I believe shouldn't be that hard), we can > modify our current guidelines to reflect these changes. In next 2 weeks I'll go > through packages that have files in /usr/lib/java and rebuild them, and also > look at packages that depend on these. I won't be around much because of > holidays for next few days, so if anyone would look into it before me: great! QUESTION: So, using 'osutil' with your proposed 'cmake' change as an example for Fedora 16 and later, are you expecting "Layout A", "Layout B", "Layout C", "Layout D", or something else? Original Layout: 32-bit: /usr/lib/java/osutil.jar -> /usr/lib/osutil/osutil.jar /usr/lib/osutil/ /usr/lib/osutil/libosutil.so /usr/lib/osutil/osutil-2.0.1.jar /usr/lib/osutil/osutil.jar -> osutil-2.0.1.jar 64-bit: /usr/lib/java/osutil.jar -> /usr/lib64/osutil/osutil.jar /usr/lib64/osutil/ /usr/lib64/osutil/libosutil.so /usr/lib64/osutil/osutil-2.0.1.jar /usr/lib64/osutil/osutil.jar -> osutil-2.0.1.jar Layout A (identical for 32-bit; relocates jar symlink for 64-bit; no java code changes): 32-bit: /usr/lib/java/osutil.jar -> /usr/lib/osutil/osutil.jar /usr/lib/osutil/ /usr/lib/osutil/libosutil.so /usr/lib/osutil/osutil-2.0.1.jar /usr/lib/osutil/osutil.jar -> osutil-2.0.1.jar 64-bit: /usr/lib64/java/osutil.jar -> /usr/lib64/osutil/osutil.jar /usr/lib64/osutil/ /usr/lib64/osutil/libosutil.so /usr/lib64/osutil/osutil-2.0.1.jar /usr/lib64/osutil/osutil.jar -> osutil-2.0.1.jar Layout B (replaces jar symlink with jar; relocates jar for 64-bit; removes versioned jar + jar symlink; no java code changes): 32-bit: /usr/lib/java/osutil.jar /usr/lib/osutil/ /usr/lib/osutil/libosutil.so 64-bit: /usr/lib64/java/osutil.jar /usr/lib64/osutil/ /usr/lib64/osutil/libosutil.so Layout C (adds javajnidir symlink; replaces jar symlink with jar; relocates jar for 64-bit; removes versioned jar + jar symlink; no java code changes): 32-bit: /usr/share/java-jni/osutil.jar -> /usr/lib/osutil/osutil.jar /usr/lib/java/osutil.jar /usr/lib/osutil/ /usr/lib/osutil/libosutil.so 64-bit: /usr/share/java-jni/osutil.jar -> /usr/lib64/osutil/osutil.jar /usr/lib64/java/osutil.jar /usr/lib64/osutil/ /usr/lib64/osutil/libosutil.so Layout D (adds javajnidir symlink; relocates jar symlink for 64-bit; removes versioned jar; replaces jar symlink with jar; no java code changes): 32-bit: /usr/share/java-jni/osutil.jar -> /usr/lib/osutil/osutil.jar /usr/lib/java/osutil.jar -> /usr/lib/osutil/osutil.jar /usr/lib/osutil/ /usr/lib/osutil/libosutil.so /usr/lib/osutil/osutil.jar 64-bit: /usr/share/java-jni/osutil.jar -> /usr/lib64/osutil/osutil.jar /usr/lib64/java/osutil.jar -> /usr/lib64/osutil/osutil.jar /usr/lib64/osutil/ /usr/lib64/osutil/libosutil.so /usr/lib64/osutil/osutil.jar Since %{_javajnidir} (/usr/share/java-jni/) is supposed to be used for jar files that use JNI jars and they are not using JNI themselves and are architecture agnostic, options C and D are not good. That's because osutil.jar directly uses JNI calls. It should therefore place jar file into %{_jnidir} (/usr/lib[64]/java). I like option B better because it has less clutter, but both A and B could be used, depending on the wishes of maintainer. That's because they both keep multilib OK. Personally I'd prefer B since it has less work for packager I'd say (no symlinks to deal with). Does this make sense at all? Best example of javajnidir I've seen is jansi-native package. The package has 2 jars: one is completely noarch, the other contains *so file inside. But the noarch jar is still useless without the arch jar. FYI I later found out it was enough to do: -%cmake -DBUILD_OSUTIL:BOOL=ON .. +%cmake -DBUILD_OSUTIL:BOOL=ON -DJAVA_LIB_INSTALL_DIR=%{_jnidir} .. when building osutil to fix jar placing. (In reply to comment #40) > Since %{_javajnidir} (/usr/share/java-jni/) is supposed to be used for jar > files that use JNI jars and they are not using JNI themselves and are > architecture agnostic, options C and D are not good. That's because osutil.jar > directly uses JNI calls. > > It should therefore place jar file into %{_jnidir} (/usr/lib[64]/java). I like > option B better because it has less clutter, but both A and B could be used, > depending on the wishes of maintainer. That's because they both keep multilib > OK. Personally I'd prefer B since it has less work for packager I'd say (no > symlinks to deal with). > B is fine -- this means that these legacy packages will not use %{_javajnidir} at all -- and hopefully everything will work -- although I think that I may need to alter some wrappers that we use for some of our command line tools to perform the search correctly, as I believe that these may not use "build-classpath". > Does this make sense at all? Best example of javajnidir I've seen is > jansi-native package. The package has 2 jars: one is completely noarch, the > other contains *so file inside. But the noarch jar is still useless without the > arch jar. > > FYI I later found out it was enough to do: > -%cmake -DBUILD_OSUTIL:BOOL=ON .. > +%cmake -DBUILD_OSUTIL:BOOL=ON -DJAVA_LIB_INSTALL_DIR=%{_jnidir} .. > > when building osutil to fix jar placing. Awesome. This is far more elegant and easier to implement. (In reply to comment #38) > So I decided to bite the bullet and did changes that will break things I am > sure: > > %_jnidir is now %_libdir/java > %_javajnidir is new addition for noarch jars using arch-specific bits from > %_jnidir > > build-classpath has been changed to resolve from this new directory as well. > Maven is also resolving from _jnidir and _javajnidir (it didn't before). > > This change will break builds and in a few cases patches will need to be > created to fix them. I've tested with osutil. I had to fix cmake-> > - "${CMAKE_INSTALL_PREFIX}/lib/java" > + "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/java" > > And that was it. I would be really interested how many things broke because of > these changes. > > If we can make this work (which I believe shouldn't be that hard), we can > modify our current guidelines to reflect these changes. In next 2 weeks I'll go > through packages that have files in /usr/lib/java and rebuild them, and also > look at packages that depend on these. I won't be around much because of > holidays for next few days, so if anyone would look into it before me: great! rmeggins discovered that this broke the old behavior of a JNI jar located under '/usr/lib/java' on a 64-bit platform; although he was able to manually move the 'jss4.jar' file that he needed under '/usr/lib64/java' to make it work, shouldn't the correct behavior of this fix be to first look in the new '/usr/lib/java-jni' directory, followed by looking in the "/usr/lib64/java" directory, AND then finally in "/usr/lib/java" for JNI jars? I believe that this method would allow things to continue to work until such time as all JNI packages can be changed to conform with this new layout. (In reply to comment #42) > (In reply to comment #38) > > So I decided to bite the bullet and did changes that will break things I am > > sure: > > > > %_jnidir is now %_libdir/java > > %_javajnidir is new addition for noarch jars using arch-specific bits from > > %_jnidir > > > > build-classpath has been changed to resolve from this new directory as well. > > Maven is also resolving from _jnidir and _javajnidir (it didn't before). > > > > This change will break builds and in a few cases patches will need to be > > created to fix them. I've tested with osutil. I had to fix cmake-> > > - "${CMAKE_INSTALL_PREFIX}/lib/java" > > + "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/java" > > > > And that was it. I would be really interested how many things broke because of > > these changes. > > > > If we can make this work (which I believe shouldn't be that hard), we can > > modify our current guidelines to reflect these changes. In next 2 weeks I'll go > > through packages that have files in /usr/lib/java and rebuild them, and also > > look at packages that depend on these. I won't be around much because of > > holidays for next few days, so if anyone would look into it before me: great! > > rmeggins discovered that this broke the old behavior of a JNI jar located under > '/usr/lib/java' on a 64-bit platform; although he was able to manually move > the 'jss4.jar' file that he needed under '/usr/lib64/java' to make it work, > shouldn't the correct behavior of this fix be to first look in the new > '/usr/lib/java-jni' directory, followed by looking in the "/usr/lib64/java" > directory, AND then finally in "/usr/lib/java" for JNI jars? > > I believe that this method would allow things to continue to work until such > time as all JNI packages can be changed to conform with this new layout. Also, wouldn't this be necessary anyway in case an individual is running a 32-bit JVM on a 64-bit platform, or does jpackage-utils check for the bitness of the JVM? Closing the bug as build-classpath swt works now. Please open other bugs to keep bugs on topic, there is simply too much in this one. |