Skip to content

Commit

Permalink
[FIXED JENKINS-14351] jna-posix → jnr-posix upgrade (opt in).
Browse files Browse the repository at this point in the history
  • Loading branch information
jglick committed May 31, 2013
1 parent be5cd4f commit 2a1d163
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 28 deletions.
3 changes: 3 additions & 0 deletions changelog.html
Expand Up @@ -61,6 +61,9 @@
<li class=bug>
Optimizations in fingerprint recording.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-16301">issue 16301</a>)
<li class=bug>
Using JNR-POSIX rather than JNA-POSIX for better platform support.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-14351">issue 14351</a>)
<li class='major bug'>
Errors searching build records when builds were misordered.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-15652">issue 15652</a>)
Expand Down
7 changes: 6 additions & 1 deletion core/pom.xml
Expand Up @@ -112,11 +112,16 @@ THE SOFTWARE.
</exclusions>
</dependency>

<dependency>
<dependency> <!-- for compatibility only; all new code should use JNR -->
<groupId>org.jruby.ext.posix</groupId>
<artifactId>jna-posix</artifactId>
<version>1.0.3</version>
</dependency>
<dependency>
<groupId>com.github.jnr</groupId>
<artifactId>jnr-posix</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.kohsuke</groupId>
<artifactId>trilead-putty-extension</artifactId>
Expand Down
15 changes: 9 additions & 6 deletions core/src/main/java/hudson/Util.java
Expand Up @@ -40,8 +40,8 @@
import org.apache.tools.ant.taskdefs.Chmod;
import org.apache.tools.ant.taskdefs.Copy;
import org.apache.tools.ant.types.FileSet;
import org.jruby.ext.posix.FileStat;
import org.jruby.ext.posix.POSIX;
import jnr.posix.FileStat;
import jnr.posix.POSIX;
import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement;

import javax.crypto.SecretKey;
Expand Down Expand Up @@ -281,7 +281,7 @@ private static void makeWritable(File f) {
}

try {// try libc chmod
POSIX posix = PosixAPI.get();
POSIX posix = PosixAPI.jnr();
String path = f.getAbsolutePath();
FileStat stat = posix.stat(path);
posix.chmod(path, stat.mode()|0200); // u+w
Expand Down Expand Up @@ -1073,13 +1073,16 @@ public static void createSymlink(File baseDir, String targetPath, String symlink
} catch (LinkageError e) {
// if JNA is unavailable, fall back.
// we still prefer to try JNA first as PosixAPI supports even smaller platforms.
if (PosixAPI.supportsNative()) {
r = PosixAPI.get().symlink(targetPath,symlinkFile.getAbsolutePath());
POSIX posix = PosixAPI.jnr();
if (posix.isNative()) {
// XXX should we rethrow PosixException as IOException here?
r = posix.symlink(targetPath,symlinkFile.getAbsolutePath());
}
}
}
if (r==null) {
// if all else fail, fall back to the most expensive approach of forking a process
// XXX is this really necessary? JavaPOSIX should do this automatically
r = new LocalProc(new String[]{
"ln","-s", targetPath, symlinkPath},
new String[0],listener.getLogger(), baseDir).join();
Expand Down Expand Up @@ -1221,7 +1224,7 @@ public static String resolveSymlink(File link) throws InterruptedException, IOEx
} catch (LinkageError e) {
// if JNA is unavailable, fall back.
// we still prefer to try JNA first as PosixAPI supports even smaller platforms.
return PosixAPI.get().readlink(filename);
return PosixAPI.jnr().readlink(filename);
}
}

Expand Down
Expand Up @@ -118,7 +118,7 @@ public Void invoke(File f, VirtualChannel channel) throws IOException, Interrupt
}

// try to protect this file from other users, if we can.
PosixAPI.get().chmod(f.getAbsolutePath(),0600);
PosixAPI.jnr().chmod(f.getAbsolutePath(),0600);
return null;
}
});
Expand Down
64 changes: 48 additions & 16 deletions core/src/main/java/hudson/os/PosixAPI.java
@@ -1,45 +1,74 @@
package hudson.os;

import org.jruby.ext.posix.JavaPOSIX;
import org.jruby.ext.posix.POSIX;
import org.jruby.ext.posix.POSIXFactory;
import org.jruby.ext.posix.POSIXHandler;
import org.jruby.ext.posix.POSIX.ERRORS;

import java.io.File;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.Map;
import java.util.logging.Logger;
import jnr.constants.platform.Errno;
import jnr.posix.POSIX;
import jnr.posix.POSIXFactory;
import jnr.posix.util.DefaultPOSIXHandler;

/**
* POSIX API wrapper.
*
* Formerly used the jna-posix library, but this has been superseded by jnr-posix.
* @author Kohsuke Kawaguchi
*/
public class PosixAPI {
public static POSIX get() {

private static POSIX posix;

/**
* Load the JNR implementation of the POSIX APIs for the current platform.
* Runtime exceptions will be of type {@link PosixException}.
* @return some implementation (even on Windows or unsupported Unix)
* @since 1.518
*/
public static synchronized POSIX jnr() {
if (posix == null) {
posix = POSIXFactory.getPOSIX(new DefaultPOSIXHandler() {
@Override public void error(Errno error, String extraData) {
throw new PosixException("native error " + error.description() + " " + extraData, convert(error));
}
@Override public void error(Errno error, String methodName, String extraData) {
throw new PosixException("native error calling " + methodName + ": " + error.description() + " " + extraData, convert(error));
}
private org.jruby.ext.posix.POSIX.ERRORS convert(Errno error) {
try {
return org.jruby.ext.posix.POSIX.ERRORS.valueOf(error.name());
} catch (IllegalArgumentException x) {
return org.jruby.ext.posix.POSIX.ERRORS.EIO; // PosixException.message has real error anyway
}
}
}, true);
}
return posix;
}

/**
* @deprecated as of 1.448
* Use {@link #supportsNative()}.
* @deprecated use {@link #jnr} and {@link POSIX#isNative}
*/
@Deprecated
public boolean isNative() {
return supportsNative();
}

/**
* Determine if the jna-posix library could not provide native support, and
* used a fallback java implementation which does not support many operations.
* @deprecated use {@link #jnr} and {@link POSIX#isNative}
*/
@Deprecated
public static boolean supportsNative() {
return !(posix instanceof JavaPOSIX);
return !(jnaPosix instanceof org.jruby.ext.posix.JavaPOSIX);
}

private static final POSIX posix = POSIXFactory.getPOSIX(new POSIXHandler() {
public void error(ERRORS errors, String s) {

private static org.jruby.ext.posix.POSIX jnaPosix;
/** @deprecated Use {@link #jnr} instead. */
@Deprecated
public static synchronized org.jruby.ext.posix.POSIX get() {
if (jnaPosix == null) {
jnaPosix = org.jruby.ext.posix.POSIXFactory.getPOSIX(new org.jruby.ext.posix.POSIXHandler() {
public void error(org.jruby.ext.posix.POSIX.ERRORS errors, String s) {
throw new PosixException(s,errors);
}

Expand Down Expand Up @@ -87,6 +116,9 @@ public PrintStream getErrorStream() {
return System.err;
}
}, true);
}
return jnaPosix;
}

private static final Logger LOGGER = Logger.getLogger(PosixAPI.class.getName());
}
4 changes: 3 additions & 1 deletion core/src/main/java/hudson/os/PosixException.java
Expand Up @@ -4,7 +4,7 @@

/**
* Indicates an error during POSIX API call.
*
* @see PosixAPI
* @author Kohsuke Kawaguchi
*/
public class PosixException extends RuntimeException {
Expand All @@ -15,6 +15,8 @@ public PosixException(String message, ERRORS errors) {
this.errors = errors;
}

/** @deprecated Leaks reference to deprecated jna-posix API. */
@Deprecated
public ERRORS getErrorCode() {
return errors;
}
Expand Down
Expand Up @@ -137,7 +137,7 @@ private void process(File f) {
} 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);
PosixAPI.jnr().chmod(f.getAbsolutePath(),0755);
}
}
} else {
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/hudson/util/IOUtils.java
Expand Up @@ -122,7 +122,7 @@ public static boolean isAbsolute(String path) {
*/
public static int mode(File f) throws PosixException {
if(Functions.isWindows()) return -1;
return PosixAPI.get().stat(f.getPath()).mode();
return PosixAPI.jnr().stat(f.getPath()).mode();
}

/**
Expand Down
4 changes: 3 additions & 1 deletion core/src/main/java/hudson/util/jna/GNUCLibrary.java
Expand Up @@ -30,6 +30,8 @@
import com.sun.jna.Memory;
import com.sun.jna.NativeLong;
import com.sun.jna.ptr.IntByReference;
import hudson.os.PosixAPI;
import jnr.posix.POSIX;
import org.jvnet.libpam.impl.CLibrary.passwd;

/**
Expand All @@ -38,7 +40,7 @@
* <p>
* 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.
*
* <p>Consider deprecating all methods present also in {@link POSIX} (as obtained by {@link PosixAPI#jnr}).
* @author Kohsuke Kawaguchi
*/
public interface GNUCLibrary extends Library {
Expand Down

0 comments on commit 2a1d163

Please sign in to comment.