NativeUtils.java 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package de.nplusc.izc.tools.IOtools;
  2. import java.io.File;
  3. import java.io.FileNotFoundException;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.io.OutputStream;
  8. /**
  9. * Simple library class for working with JNI (Java Native Interface)
  10. *
  11. * @see http://adamheinrich.com/2012/how-to-load-native-jni-library-from-jar
  12. *
  13. * @author Adam Heirnich <adam@adamh.cz>, http://www.adamh.cz
  14. */
  15. public class NativeUtils {
  16. /**
  17. * Private constructor - this class will never be instanced
  18. */
  19. private NativeUtils() {
  20. }
  21. /**
  22. * Loads library from current JAR archive
  23. *
  24. * The file from JAR is copied into system temporary directory and then loaded. The temporary file is deleted after exiting.
  25. * Method uses String as filename because the pathname is "abstract", not system-dependent.
  26. *
  27. * @param path The filename inside JAR as absolute path (beginning with '/'), e.g. /package/File.ext
  28. * @throws IOException If temporary file creation or read/write operation fails
  29. * @throws IllegalArgumentException If source file (param path) does not exist
  30. * @throws IllegalArgumentException If the path is not absolute or if the filename is shorter than three characters (restriction of {@see File#createTempFile(java.lang.String, java.lang.String)}).
  31. */
  32. public static void loadLibraryFromJar(String path) throws IOException {
  33. if (!path.startsWith("/")) {
  34. throw new IllegalArgumentException("The path has to be absolute (start with '/').");
  35. }
  36. // Obtain filename from path
  37. String[] parts = path.split("/");
  38. String filename = (parts.length > 1) ? parts[parts.length - 1] : null;
  39. // Split filename to prexif and suffix (extension)
  40. String prefix = "";
  41. String suffix = null;
  42. if (filename != null) {
  43. parts = filename.split("\\.", 2);
  44. prefix = parts[0];
  45. suffix = (parts.length > 1) ? "."+parts[parts.length - 1] : null; // Thanks, davs! :-)
  46. }
  47. // Check if the filename is okay
  48. if (filename == null || prefix.length() < 3) {
  49. throw new IllegalArgumentException("The filename has to be at least 3 characters long.");
  50. }
  51. // Prepare temporary file
  52. File temp = File.createTempFile(prefix, suffix);
  53. temp.deleteOnExit();
  54. if (!temp.exists()) {
  55. throw new FileNotFoundException("File " + temp.getAbsolutePath() + " does not exist.");
  56. }
  57. // Prepare buffer for data copying
  58. byte[] buffer = new byte[1024];
  59. int readBytes;
  60. // Open and check input stream
  61. InputStream is = NativeUtils.class.getResourceAsStream(path);
  62. if (is == null) {
  63. throw new FileNotFoundException("File " + path + " was not found inside JAR.");
  64. }
  65. // Open output stream and copy data between source file in JAR and the temporary file
  66. OutputStream os = new FileOutputStream(temp);
  67. try {
  68. while ((readBytes = is.read(buffer)) != -1) {
  69. os.write(buffer, 0, readBytes);
  70. }
  71. } finally {
  72. // If read/write fails, close streams safely before throwing an exception
  73. os.close();
  74. is.close();
  75. }
  76. // Finally, load the library
  77. System.load(temp.getAbsolutePath());
  78. }
  79. }