Skip to content

Commit

Permalink
Configure the TFS SDK native folder's location automatically.
Browse files Browse the repository at this point in the history
This avoids having to add the com.microsoft.tfs.jni.native.base-directory property in the container's configuration file.
Added an integration test to verify the functionality.
  • Loading branch information
olivierdagenais committed Oct 8, 2013
1 parent 0f719b1 commit 88baa47
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 0 deletions.
22 changes: 22 additions & 0 deletions src/main/java/hudson/plugins/tfs/model/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@
import hudson.plugins.tfs.commands.ServerConfigurationProvider;
import hudson.plugins.tfs.util.MaskedArgumentListBuilder;

import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.net.URI;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.HashMap;
import java.util.Map;

Expand All @@ -19,6 +23,7 @@

public class Server implements ServerConfigurationProvider {

private static final String nativeFolderPropertyName = "com.microsoft.tfs.jni.native.base-directory";
private final String url;
private final String userName;
private final String userPassword;
Expand All @@ -45,6 +50,7 @@ else if (username != null && password != null) {
}

if (credentials != null) {
ensureNativeLibrariesConfigured();
// TODO: TFSTeamProjectCollection implements Closeable
// and should be disposed as soon as no longer needed.
this.tpc = new TFSTeamProjectCollection(uri, credentials);
Expand All @@ -54,6 +60,22 @@ else if (username != null && password != null) {
}
}

static synchronized void ensureNativeLibrariesConfigured() {
final String nativeFolder = System.getProperty(nativeFolderPropertyName);
if (nativeFolder == null) {
final Class<TFSTeamProjectCollection> metaclass = TFSTeamProjectCollection.class;
final ProtectionDomain protectionDomain = metaclass.getProtectionDomain();
final CodeSource codeSource = protectionDomain.getCodeSource();
// TODO: codeSource could be null; what should we do, then?
final URL location = codeSource.getLocation();
final String stringPathToJar = location.getFile();
final File pathToJar = new File(stringPathToJar);
final File pathToLibFolder = pathToJar.getParentFile();
final File pathToNativeFolder = new File(pathToLibFolder, "native");
System.setProperty(nativeFolderPropertyName, pathToNativeFolder.toString());
}
}

Server(String url) {
this(null, url, null, null);
}
Expand Down
25 changes: 25 additions & 0 deletions src/test/java/hudson/plugins/tfs/model/ServerIntegrationTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package hudson.plugins.tfs.model;

import org.jvnet.hudson.test.JenkinsRule;
import org.junit.Rule;
import org.junit.Test;

import com.microsoft.tfs.core.TFSTeamProjectCollection;
import com.microsoft.tfs.core.exceptions.TECoreException;

public class ServerIntegrationTest {

@Rule public JenkinsRule j = new JenkinsRule();

@Test(expected = TECoreException.class)
/**
* It's OK for this test to throw a TECoreException for "unknown host";
* it means we were able to load the native libraries,
* otherwise an @link UnsatisfiedLinkError would have been thrown earlier.
*/
public void canFindTfsSdkNativeLibraries() {
final Server server = new Server(null, "http://tfs.invalid:8080/tfs", "username", "password");
final TFSTeamProjectCollection tpc = server.getTeamProjectCollection();
tpc.getVersionControlClient();
}
}

0 comments on commit 88baa47

Please sign in to comment.