Throw NativeIntegrationUnavailableException when an integration is not supported, and NativeException when something goes wrong loading the integration.

This commit is contained in:
Adam Murdoch
2012-09-01 10:29:43 +10:00
parent ba2a54b403
commit b8b96291c6
4 changed files with 50 additions and 38 deletions

View File

@@ -126,7 +126,7 @@ You can run `$INSTALL_DIR/bin/native-platform` to run the test application.
* Split into multiple projects. * Split into multiple projects.
* Convert to c. * Convert to c.
* Thread safety. * Thread safety.
* Improve error message when unsupported capability is used. * Make native library extraction multi-process safe.
* Initial release. * Initial release.
* Use fully decomposed form for unicode file names on hfs+ filesystems. * Use fully decomposed form for unicode file names on hfs+ filesystems.
* Handle string encoding for file system details. * Handle string encoding for file system details.

View File

@@ -26,9 +26,6 @@ public class Native {
synchronized (lock) { synchronized (lock) {
if (!loaded) { if (!loaded) {
Platform platform = Platform.current(); Platform platform = Platform.current();
if (!platform.isSupported()) {
throw new NativeException(String.format("The current platform is not supported."));
}
try { try {
File libFile; File libFile;
URL resource = Native.class.getClassLoader().getResource(platform.getLibraryName()); URL resource = Native.class.getClassLoader().getResource(platform.getLibraryName());
@@ -46,9 +43,6 @@ public class Native {
libFile = new File("build/binaries/" + platform.getLibraryName()); libFile = new File("build/binaries/" + platform.getLibraryName());
} }
System.load(libFile.getCanonicalPath()); System.load(libFile.getCanonicalPath());
} catch (IOException e) {
throw new RuntimeException(e);
}
int nativeVersion = NativeLibraryFunctions.getVersion(); int nativeVersion = NativeLibraryFunctions.getVersion();
if (nativeVersion != NativeLibraryFunctions.VERSION) { if (nativeVersion != NativeLibraryFunctions.VERSION) {
throw new NativeException(String.format( throw new NativeException(String.format(
@@ -56,6 +50,11 @@ public class Native {
NativeLibraryFunctions.VERSION)); NativeLibraryFunctions.VERSION));
} }
loaded = true; loaded = true;
} catch (NativeException e) {
throw e;
} catch (Exception e) {
throw new NativeException("Failed to initialise native integration.", e);
}
} }
} }
} }
@@ -64,18 +63,15 @@ public class Native {
* Locates a native integration of the given type. * Locates a native integration of the given type.
* *
* @return The native integration. * @return The native integration.
* @throws UnsupportedOperationException if the given integration is not available. * @throws NativeIntegrationUnavailableException When the given native integration is not available on the current
* machine.
* @throws NativeException On failure to load the native integration.
*/ */
public static <T extends NativeIntegration> T get(Class<T> type) throws UnsupportedOperationException { public static <T extends NativeIntegration> T get(Class<T> type)
throws NativeIntegrationUnavailableException, NativeException {
init(null); init(null);
Platform platform = Platform.current(); Platform platform = Platform.current();
T integration = platform.get(type); return platform.get(type);
if (integration != null) {
return integration;
}
throw new UnsupportedOperationException(String.format("Cannot load unsupported native integration %s.",
type.getName()));
} }
private static void copy(URL source, File dest) { private static void copy(URL source, File dest) {

View File

@@ -0,0 +1,10 @@
package net.rubygrapefruit.platform;
/**
* Thrown when a given integration is not available for the current machine.
*/
public class NativeIntegrationUnavailableException extends NativeException {
public NativeIntegrationUnavailableException(String message) {
super(message);
}
}

View File

@@ -10,8 +10,8 @@ public abstract class Platform {
public static Platform current() { public static Platform current() {
synchronized (Platform.class) { synchronized (Platform.class) {
if (platform == null) { if (platform == null) {
String osName = System.getProperty("os.name").toLowerCase(); String osName = getOperatingSystem().toLowerCase();
String arch = System.getProperty("os.arch"); String arch = getArchitecture();
if (osName.contains("windows")) { if (osName.contains("windows")) {
platform = new Windows(); platform = new Windows();
} else if (osName.contains("linux")) { } else if (osName.contains("linux")) {
@@ -28,19 +28,16 @@ public abstract class Platform {
} }
} }
public boolean isSupported() {
return true;
}
public boolean isWindows() { public boolean isWindows() {
return false; return false;
} }
public <T extends NativeIntegration> T get(Class<T> type) { public <T extends NativeIntegration> T get(Class<T> type) {
return null; throw new NativeIntegrationUnavailableException(String.format("Native integration %s is not supported on this operating system (%s %s)",
type.getName(), getOperatingSystem(), getArchitecture()));
} }
public abstract String getLibraryName(); public abstract String getLibraryName() throws NativeIntegrationUnavailableException;
private static class Windows extends Platform { private static class Windows extends Platform {
@Override @Override
@@ -105,11 +102,19 @@ public abstract class Platform {
@Override @Override
public String getLibraryName() { public String getLibraryName() {
if (System.getProperty("os.arch").equals("amd64")) { if (getArchitecture().equals("amd64")) {
return "libnative-linux-amd64.so"; return "libnative-linux-amd64.so";
} }
if (getArchitecture().equals("i386")) {
return "libnative-linux-i386.so"; return "libnative-linux-i386.so";
} }
throw new NativeIntegrationUnavailableException(String.format(
"Native integration is not available for this architecture (%s) on Linux.", getArchitecture()));
}
}
private static String getArchitecture() {
return System.getProperty("os.arch");
} }
private static class Solaris extends Unix { private static class Solaris extends Unix {
@@ -135,13 +140,14 @@ public abstract class Platform {
} }
private static class Unsupported extends Platform { private static class Unsupported extends Platform {
@Override public String getLibraryName() {
public boolean isSupported() { throw new NativeIntegrationUnavailableException(String.format(
return false; "Native integration is not available for this operating system (%s %s)", getOperatingSystem(),
getArchitecture()));
}
} }
public String getLibraryName() { private static String getOperatingSystem() {
throw new UnsupportedOperationException(); return System.getProperty("os.name");
}
} }
} }