diff --git a/pom.xml b/pom.xml
index 60c17b0..8f2535e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -48,6 +48,7 @@
${findbugs-maven-plugin.version}
Max
+ Low
true
false
@@ -86,6 +87,11 @@
3.0.0
provided
+
+ org.kohsuke
+ access-modifier-annotation
+ 1.7
+
@@ -94,6 +100,13 @@
gitsite:git@github.com/kohsuke/${project.artifactId}.git
+
+
+
+ repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/public/
+
+
diff --git a/src/main/java/org/jvnet/winp/Main.java b/src/main/java/org/jvnet/winp/Main.java
index 2de5f4d..1f6b046 100644
--- a/src/main/java/org/jvnet/winp/Main.java
+++ b/src/main/java/org/jvnet/winp/Main.java
@@ -1,10 +1,14 @@
package org.jvnet.winp;
+import org.kohsuke.accmod.Restricted;
+import org.kohsuke.accmod.restrictions.NoExternalUse;
+
/**
* Test driver class
*
* @author Kohsuke Kawaguchi
*/
+@Restricted(NoExternalUse.class)
public class Main {
public static void main(String[] args) {
WinProcess.enableDebugPrivilege();
diff --git a/src/main/java/org/jvnet/winp/Native.java b/src/main/java/org/jvnet/winp/Native.java
index 4f04dcf..7a57caf 100755
--- a/src/main/java/org/jvnet/winp/Native.java
+++ b/src/main/java/org/jvnet/winp/Native.java
@@ -10,6 +10,8 @@
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
/**
* Functions defined in the DLL.
@@ -55,13 +57,16 @@ class Native {
private static final Logger LOGGER = Logger.getLogger(Native.class.getName());
// system property holding the preferred folder for copying the dll file to.
private static final String DLL_TARGET = "winp.folder.preferred";
+ //TODO: usage of this field has been removed in https://github.com/kohsuke/winp/pull/27
+ // Likely it needs to be fixed
private static final String UNPACK_DLL_TO_PARENT_DIR = "winp.unpack.dll.to.parent.dir";
static {
load();
}
- private static String md5(URL res) {
+ @Nonnull
+ private static String md5(@Nonnull URL res) throws IOException {
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
InputStream in = res.openStream();
@@ -75,13 +80,13 @@ private static String md5(URL res) {
in.close();
}
} catch (NoSuchAlgorithmException e) {
- throw new AssertionError(e);
+ throw new IOException("Cannot find MD5 algorithm", e);
} catch (IOException e) {
- throw new Error("failed to checksum " + res + ": " + e, e);
+ throw new IOException("failed to checksum " + res + ": " + e, e);
}
}
- private static void load() {
+ private static void load() throws UnsatisfiedLinkError {
final URL res = Native.class.getClassLoader().getResource(DLL_NAME + ".dll");
@@ -100,7 +105,7 @@ private static void load() {
}
}
- private static void loadByUrl(URL res) throws IOException {
+ private static void loadByUrl(@Nonnull URL res) throws IOException {
String url = res.toExternalForm();
@@ -128,11 +133,12 @@ private static void loadByUrl(URL res) throws IOException {
loadDll(dllFile);
}
- private static File extractToStaticLocation(URL url) throws IOException {
+ @Nonnull
+ private static File extractToStaticLocation(@Nonnull URL url) throws IOException {
File jarFile = getJarFile(url);
if (jarFile == null) {
- throw new RuntimeException("Failed to locate JAR file by URL " + url);
+ throw new IOException("Failed to locate JAR file by URL " + url);
}
String preferred = System.getProperty(DLL_TARGET);
@@ -143,7 +149,8 @@ private static File extractToStaticLocation(URL url) throws IOException {
return destFile;
}
- private static File extractToTmpLocation(URL res) throws IOException {
+ @Nonnull
+ private static File extractToTmpLocation(@Nonnull URL res) throws IOException {
File tmpFile = File.createTempFile(DLL_NAME, ".dll");
tmpFile.deleteOnExit();
@@ -151,7 +158,8 @@ private static File extractToTmpLocation(URL res) throws IOException {
return tmpFile;
}
- private static File getJarFile(URL res) {
+ @CheckForNull
+ /**package*/ static File getJarFile(@Nonnull URL res) {
String url = res.toExternalForm();
if (!(url.startsWith("jar:") || url.startsWith("wsjar:"))) {
@@ -175,6 +183,7 @@ private static File getJarFile(URL res) {
// this indicates file://host/path-in-host format
// Windows maps UNC path to this. On Unix, there's no well defined
// semantics for this.
+ LOGGER.log(Level.FINE, "file://PATH semantics is used. On Unix the behavior is undefined, hence the results may differ from the expectation.");
}
filePortion = URLDecoder.decode(filePortion);
@@ -226,7 +235,8 @@ private static void copyStream(InputStream in, OutputStream out) throws IOExcept
/**
* Convert 128bit data into hex string.
*/
- private static String toHex32(byte[] b) {
+ @Nonnull
+ private static String toHex32(@Nonnull byte[] b) {
return String.format("%032X",new BigInteger(1,b));
}
}
diff --git a/src/main/java/org/jvnet/winp/WinProcess.java b/src/main/java/org/jvnet/winp/WinProcess.java
index 63a58f2..67c66f8 100755
--- a/src/main/java/org/jvnet/winp/WinProcess.java
+++ b/src/main/java/org/jvnet/winp/WinProcess.java
@@ -1,13 +1,17 @@
package org.jvnet.winp;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.lang.reflect.Field;
import java.util.Comparator;
import java.util.TreeMap;
import java.util.Iterator;
+import java.util.Locale;
+import java.util.NoSuchElementException;
import java.util.logging.Level;
import java.util.logging.Logger;
import static java.util.logging.Level.FINE;
+import javax.annotation.Nonnull;
/**
* Represents a Windows process.
@@ -36,8 +40,12 @@ public WinProcess(int pid) {
/**
* Wraps {@link Process} into {@link WinProcess}.
+ *
+ * @param proc Process to be wrapped
*/
- public WinProcess(Process proc) {
+ @SuppressFBWarnings(value = "DP_DO_INSIDE_DO_PRIVILEGED",
+ justification = "Enabled for now, the calling code is expected to have appropriate security permissions")
+ public WinProcess(@Nonnull Process proc) {
try {
Field f = proc.getClass().getDeclaredField("handle");
f.setAccessible(true);
@@ -121,13 +129,15 @@ public synchronized String getCommandLine() {
* If we fail to obtain the command line. For example,
* maybe we didn't have enough security privileges.
*/
- public synchronized TreeMap getEnvironmentVariables() {
- if(envVars==null)
+ @Nonnull
+ public synchronized TreeMap getEnvironmentVariables() {
+ if (envVars == null) {
parseCmdLineAndEnvVars();
+ }
return envVars;
}
- private void parseCmdLineAndEnvVars() {
+ private void parseCmdLineAndEnvVars() throws WinpException {
String s = Native.getCmdLineAndEnvVars(pid);
if(s==null)
throw new WinpException("Failed to obtain for PID="+pid);
@@ -157,7 +167,9 @@ private void parseCmdLineAndEnvVars() {
private static final Comparator CASE_INSENSITIVE_COMPARATOR = new Comparator() {
public int compare(String o1, String o2) {
- return o1.toUpperCase().compareTo(o2.toUpperCase());
+ // Rely on the default system locale
+ Locale loc = Locale.getDefault();
+ return o1.toUpperCase(loc).compareTo(o2.toUpperCase(loc));
}
};
@@ -192,7 +204,10 @@ public boolean hasNext() {
return pos