diff --git a/core/src/main/java/hudson/Util.java b/core/src/main/java/hudson/Util.java index 53e00d8ae3..9127a26a0d 100644 --- a/core/src/main/java/hudson/Util.java +++ b/core/src/main/java/hudson/Util.java @@ -31,6 +31,7 @@ import hudson.util.QuotedStringTokenizer; import hudson.util.VariableResolver; import hudson.util.jna.GNUCLibrary; import hudson.Proc.LocalProc; +import hudson.os.PosixAPI; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.types.FileSet; @@ -969,9 +970,15 @@ public class Util { int r; if (!SYMLINK_ESCAPEHATCH) { - r = GNUCLibrary.LIBC.symlink(targetPath,symlinkFile.getAbsolutePath()); - if (r!=0) - r = Native.getLastError(); + try { + r = GNUCLibrary.LIBC.symlink(targetPath,symlinkFile.getAbsolutePath()); + if (r!=0) + r = Native.getLastError(); + } catch (LinkageError e) { + // if JNA is unavailable, fall back. + // we still prefer to try JNA first as PosixAPI supports even smaller platforms. + r = PosixAPI.get().symlink(targetPath,symlinkFile.getAbsolutePath()); + } } else // escape hatch, until we know that the above works well. r = new LocalProc(new String[]{ "ln","-s", targetPath, symlinkPath}, diff --git a/core/src/main/java/hudson/WebAppMain.java b/core/src/main/java/hudson/WebAppMain.java index 5a14af25a3..d08e9827f7 100644 --- a/core/src/main/java/hudson/WebAppMain.java +++ b/core/src/main/java/hudson/WebAppMain.java @@ -130,35 +130,36 @@ public final class WebAppMain implements ServletContextListener { return; } - // make sure JNA works. this can fail if - // - platform is unsupported - // - JNA is already loaded in another classloader - // see http://wiki.hudson-ci.org/display/HUDSON/JNA+is+already+loaded - // TODO: or shall we instead modify Hudson to work gracefully without JNA? - try { - /* - java.lang.UnsatisfiedLinkError: Native Library /builds/apps/glassfish/domains/hudson-domain/generated/jsp/j2ee-modules/hudson-1.309/loader/com/sun/jna/sunos-sparc/libjnidispatch.so already loaded in another classloader - at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1743) - at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1674) - at java.lang.Runtime.load0(Runtime.java:770) - at java.lang.System.load(System.java:1005) - at com.sun.jna.Native.loadNativeLibraryFromJar(Native.java:746) - at com.sun.jna.Native.loadNativeLibrary(Native.java:680) - at com.sun.jna.Native.(Native.java:108) - at hudson.util.jna.GNUCLibrary.(GNUCLibrary.java:86) - at hudson.Util.createSymlink(Util.java:970) - at hudson.model.Run.run(Run.java:1174) - at hudson.matrix.MatrixBuild.run(MatrixBuild.java:149) - at hudson.model.ResourceController.execute(ResourceController.java:88) - at hudson.model.Executor.run(Executor.java:123) - */ - String.valueOf(Native.POINTER_SIZE); // this meaningless operation forces the classloading and initialization - } catch (LinkageError e) { - if (e.getMessage().contains("another classloader")) - context.setAttribute(APP,new JNADoublyLoaded(e)); - else - context.setAttribute(APP,new HudsonFailedToLoad(e)); - } +// JNA is no longer a hard requirement. It's just nice to have. See HUDSON-4820 for more context. +// // make sure JNA works. this can fail if +// // - platform is unsupported +// // - JNA is already loaded in another classloader +// // see http://wiki.hudson-ci.org/display/HUDSON/JNA+is+already+loaded +// // TODO: or shall we instead modify Hudson to work gracefully without JNA? +// try { +// /* +// java.lang.UnsatisfiedLinkError: Native Library /builds/apps/glassfish/domains/hudson-domain/generated/jsp/j2ee-modules/hudson-1.309/loader/com/sun/jna/sunos-sparc/libjnidispatch.so already loaded in another classloader +// at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1743) +// at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1674) +// at java.lang.Runtime.load0(Runtime.java:770) +// at java.lang.System.load(System.java:1005) +// at com.sun.jna.Native.loadNativeLibraryFromJar(Native.java:746) +// at com.sun.jna.Native.loadNativeLibrary(Native.java:680) +// at com.sun.jna.Native.(Native.java:108) +// at hudson.util.jna.GNUCLibrary.(GNUCLibrary.java:86) +// at hudson.Util.createSymlink(Util.java:970) +// at hudson.model.Run.run(Run.java:1174) +// at hudson.matrix.MatrixBuild.run(MatrixBuild.java:149) +// at hudson.model.ResourceController.execute(ResourceController.java:88) +// at hudson.model.Executor.run(Executor.java:123) +// */ +// String.valueOf(Native.POINTER_SIZE); // this meaningless operation forces the classloading and initialization +// } catch (LinkageError e) { +// if (e.getMessage().contains("another classloader")) +// context.setAttribute(APP,new JNADoublyLoaded(e)); +// else +// context.setAttribute(APP,new HudsonFailedToLoad(e)); +// } // make sure this is servlet 2.4 container or above try { diff --git a/core/src/main/java/hudson/tools/ZipExtractionInstaller.java b/core/src/main/java/hudson/tools/ZipExtractionInstaller.java index 808dc838b0..5628264e2c 100644 --- a/core/src/main/java/hudson/tools/ZipExtractionInstaller.java +++ b/core/src/main/java/hudson/tools/ZipExtractionInstaller.java @@ -29,6 +29,7 @@ import hudson.FilePath; import hudson.FilePath.FileCallable; import hudson.Util; import hudson.Functions; +import hudson.os.PosixAPI; import hudson.model.Node; import hudson.model.TaskListener; import hudson.model.Hudson; @@ -130,8 +131,15 @@ public class ZipExtractionInstaller extends ToolInstaller { if (f.isFile()) { if(Functions.isMustangOrAbove()) f.setExecutable(true, false); - else - GNUCLibrary.LIBC.chmod(f.getAbsolutePath(),0755); + else { + try { + GNUCLibrary.LIBC.chmod(f.getAbsolutePath(),0755); + } catch (LinkageError e) { + // if JNA is unavailable, fall back. + // we still prefer to try JNA first as PosixAPI supports even smaller platforms. + PosixAPI.get().chmod(f.getAbsolutePath(),0755); + } + } } else { File[] kids = f.listFiles(); if (kids != null) { diff --git a/core/src/main/java/hudson/util/jna/GNUCLibrary.java b/core/src/main/java/hudson/util/jna/GNUCLibrary.java index 77abac527b..7353339738 100644 --- a/core/src/main/java/hudson/util/jna/GNUCLibrary.java +++ b/core/src/main/java/hudson/util/jna/GNUCLibrary.java @@ -33,6 +33,10 @@ import org.jvnet.libpam.impl.CLibrary.passwd; /** * GNU C library. * + *

+ * Not available on all platforms (such as Linux/PPC, IBM mainframe, etc.), so the caller should recover gracefully + * in case of {@link LinkageError}. See HUDSON-4820. + * * @author Kohsuke Kawaguchi */ public interface GNUCLibrary extends Library {