You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@reef.apache.org by we...@apache.org on 2015/01/09 23:01:44 UTC

incubator-reef git commit: [REEF-67] Refactor utility methods in NativeInterop

Repository: incubator-reef
Updated Branches:
  refs/heads/master fa45c5ca7 -> 13cf52250


[REEF-67] Refactor utility methods in NativeInterop

NativeInterop currently load CLR assemblies for the files provided in global
folder, but it gets files from the jar that is not necessarily and easy to
cause out of sync. This change does the following:

  * Separate load lib in a new class LibLoader  and use injection to get the
    reference of the object through JobDriver constructor
  * Load global files directly instead of getting them from jar
  * Renamed and refactored the methods to use LoadLibFromGlobal() and
    loadFromReefJar()
  * Put file names, folder names in ReefFileName class and use injection to get
    the reference in LibLoader class
  * Replaced System.out into proper Log and updated logs
  * Add LogScope for LibLoader

JIRA:
  [REEF-67]: https://issues.apache.org/jira/browse/REEF-67

Pull Request:
  Closes #48


Project: http://git-wip-us.apache.org/repos/asf/incubator-reef/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-reef/commit/13cf5225
Tree: http://git-wip-us.apache.org/repos/asf/incubator-reef/tree/13cf5225
Diff: http://git-wip-us.apache.org/repos/asf/incubator-reef/diff/13cf5225

Branch: refs/heads/master
Commit: 13cf522505d143c4a178ed402cbc9227fb2e6078
Parents: fa45c5c
Author: Julia Wang <jw...@yahoo.com>
Authored: Thu Jan 8 16:29:58 2015 -0800
Committer: Markus Weimer <we...@apache.org>
Committed: Fri Jan 9 13:03:58 2015 -0800

----------------------------------------------------------------------
 .../org/apache/reef/javabridge/LibLoader.java   | 154 +++++++++++++++++++
 .../apache/reef/javabridge/NativeInterop.java   |  98 +-----------
 .../reef/javabridge/generic/JobDriver.java      |  21 ++-
 .../runtime/common/files/REEFFileNames.java     |  24 +++
 .../reef/util/logging/LoggingScopeFactory.java  |   9 ++
 5 files changed, 208 insertions(+), 98 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/13cf5225/reef-bridge-project/reef-bridge-java/src/main/java/org/apache/reef/javabridge/LibLoader.java
----------------------------------------------------------------------
diff --git a/reef-bridge-project/reef-bridge-java/src/main/java/org/apache/reef/javabridge/LibLoader.java b/reef-bridge-project/reef-bridge-java/src/main/java/org/apache/reef/javabridge/LibLoader.java
new file mode 100644
index 0000000..fa8b459
--- /dev/null
+++ b/reef-bridge-project/reef-bridge-java/src/main/java/org/apache/reef/javabridge/LibLoader.java
@@ -0,0 +1,154 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.reef.javabridge;
+
+import org.apache.commons.compress.utils.IOUtils;
+import org.apache.reef.runtime.common.files.REEFFileNames;
+import org.apache.reef.util.logging.LoggingScope;
+import org.apache.reef.util.logging.LoggingScopeFactory;
+
+import javax.inject.Inject;
+import java.io.*;
+import java.util.Date;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Loading CLR libraries
+ */
+public class LibLoader {
+
+  private static final Logger LOG = Logger.getLogger(LibLoader.class.getName());
+
+  private static final String LIB_BIN = "/";
+  private static final String DLL_EXTENSION = ".dll";
+  private static final String USER_DIR = "user.dir";
+  private static final String[] MANAGED_DLLS = {
+      "ClrHandler",
+      "msvcr110",
+  };
+
+  private final LoggingScopeFactory loggingScopeFactory;
+
+  private final REEFFileNames reefFileNames;
+
+  @Inject
+  private LibLoader(final LoggingScopeFactory loggingScopeFactory, final REEFFileNames reefFileNames) {
+    this.loggingScopeFactory = loggingScopeFactory;
+    this.reefFileNames = reefFileNames;
+  }
+
+  /**
+   * Load CLR libraries
+   */
+  public void loadLib() throws IOException {
+    LOG.log(Level.INFO, "Loading DLLs for driver at time {0}." + new Date().toString());
+    try (final LoggingScope lb = loggingScopeFactory.loadLib()) {
+      final String tempLoadDir = System.getProperty(USER_DIR) + this.reefFileNames.getLoadDir();
+      LOG.log(Level.INFO, "load Folder: " + tempLoadDir);
+      new File(tempLoadDir).mkdir();
+
+      loadFromReefJar(this.reefFileNames.getCppBridge(), false);
+
+      loadLibFromGlobal();
+
+      for (int i = 0; i < MANAGED_DLLS.length; i++) {
+        loadFromReefJar(MANAGED_DLLS[i], true);
+      }
+    }
+    LOG.log(Level.INFO, "Done loading DLLs for Driver at time {0}." + new Date().toString());
+  }
+
+  /**
+   * Load assemblies at global folder
+   */
+  private void loadLibFromGlobal() {
+    final String globalFilePath = System.getProperty(USER_DIR) + this.reefFileNames.getReefGlobal();
+    final File[] files = new File(globalFilePath).listFiles(new FilenameFilter() {
+      public boolean accept(File dir, String name) {
+        return name.toLowerCase().endsWith(DLL_EXTENSION);
+      }
+    });
+
+    LOG.log(Level.INFO, "Total dll files to load from {0} is {1}.", new Object[] {globalFilePath, files.length} );
+    for (int i = 0; i < files.length; i++) {
+      try {
+        LOG.log(Level.INFO, "file to load : " + files[i].toString());
+        NativeInterop.loadClrAssembly(files[i].toString());
+      } catch (final Exception e) {
+        LOG.log(Level.SEVERE, "exception in loading dll library: ", files[i].toString());
+        throw e;
+      }
+    }
+  }
+
+  /**
+   * Get file from jar file and copy it to temp dir and loads the library to memory
+  **/
+  private void loadFromReefJar(String name, final boolean managed) throws IOException {
+
+    name = name + DLL_EXTENSION;
+    try {
+      File fileOut = null;
+      // get input file from jar
+      final String path = this.reefFileNames.getReefDriverAppDllDir() + name;
+      LOG.log(Level.INFO, "Source file path: " + path);
+      final java.net.URL url = NativeInterop.class.getClass().getResource(path);
+      if (url != null) {
+        LOG.log(Level.INFO, "Source file: " + url.getPath());
+      }
+      try (final InputStream in = NativeInterop.class.getResourceAsStream(path)) {
+        //copy to /reef/CLRLoadingDirectory
+        final String tempLoadDir = System.getProperty(USER_DIR) + this.reefFileNames.getLoadDir();
+        fileOut = new File(tempLoadDir + LIB_BIN + name);
+        LOG.log(Level.INFO, "Destination file: " + fileOut.toString());
+        if (null == in) {
+          LOG.log(Level.WARNING, "Cannot find " + path);
+          return;
+        }
+        try (final OutputStream out = new FileOutputStream(fileOut) ) {
+          IOUtils.copy(in, out);
+        }
+      }
+      loadAssembly(fileOut, managed);
+    } catch (final FileNotFoundException e) {
+      LOG.log(Level.SEVERE, "File not find exception: ", name);
+      throw e;
+    } catch (IOException e) {
+      LOG.log(Level.SEVERE, "File copy error: ", name);
+      throw e;
+    }
+  }
+
+  /**
+   * load assembly
+   * @param fileOut
+   * @param managed
+   */
+  private void loadAssembly(final File fileOut, final boolean managed) {
+    if (managed) {
+      NativeInterop.loadClrAssembly(fileOut.toString());
+      LOG.log(Level.INFO, "Loading DLL managed done");
+    } else {
+      System.load(fileOut.toString());
+      LOG.log(Level.INFO, "Loading DLL not managed done");
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/13cf5225/reef-bridge-project/reef-bridge-java/src/main/java/org/apache/reef/javabridge/NativeInterop.java
----------------------------------------------------------------------
diff --git a/reef-bridge-project/reef-bridge-java/src/main/java/org/apache/reef/javabridge/NativeInterop.java b/reef-bridge-project/reef-bridge-java/src/main/java/org/apache/reef/javabridge/NativeInterop.java
index 5d99a3c..9fe61c1 100644
--- a/reef-bridge-project/reef-bridge-java/src/main/java/org/apache/reef/javabridge/NativeInterop.java
+++ b/reef-bridge-project/reef-bridge-java/src/main/java/org/apache/reef/javabridge/NativeInterop.java
@@ -18,14 +18,9 @@
  */
 package org.apache.reef.javabridge;
 
-import org.apache.commons.compress.utils.IOUtils;
-
-import java.io.*;
-import java.util.Date;
 import java.util.HashMap;
 
 public class NativeInterop {
-
   public static final String CLASS_HIERARCHY_FILENAME = "clrClassHierarchy.bin";
   public static final String GLOBAL_LIBRARIES_FILENAME = "userSuppliedGlobalLibraries.txt";
   public static final String EvaluatorRequestorKey = "EvaluatorRequestor";
@@ -67,23 +62,7 @@ public class NativeInterop {
     }
   };
 
-
   public static final int nHandlers = 17;
-  private static final String LIB_BIN = "/";
-  private static final String DLL_EXTENSION = ".dll";
-  private static final String CPP_BRIDGE = "JavaClrBridge";
-  private static final String tmpLoadingDirectory = System.getProperty("user.dir") + "/reef/CLRLoadingDirectory";
-  private static final String[] managedDlls = {
-      "ClrHandler",
-      "msvcr110",
-  };
-
-  static {
-    System.out.println("============== Driver Bridge initiated, loading DLLs at time " + new Date().toString() + "============== ");
-    new File(tmpLoadingDirectory).mkdir();
-    loadFromJar();
-    System.out.println("================== Done loading dlls for Driver at time " + new Date().toString() + " ================== \n");
-  }
 
   public static native void loadClrAssembly(String filePath);
 
@@ -184,79 +163,4 @@ public class NativeInterop {
       long handle,
       RunningTaskBridge runningTaskBridge
   );
-
-  private static void loadFromJar() {
-    // we need to put both DLLs to temp dir
-    loadLib(CPP_BRIDGE, false);
-    final File[] files = new File(System.getProperty("user.dir") + "/reef/global").listFiles(new FilenameFilter() {
-      public boolean accept(File dir, String name) {
-        return name.toLowerCase().endsWith(DLL_EXTENSION);
-      }
-    });
-    //System.out.println("Total dll files to load from " + System.getProperty("user.dir") + "/reef/global" + "  are: " + files.length );
-
-    for (int i = 0; i < files.length; i++) {
-      try {
-        final String fileName = files[i].getName();
-        String fileNameWithoutExtension = fileName;
-        if (fileName.indexOf(".") > 0) {
-          fileNameWithoutExtension = fileName.substring(0, fileName.lastIndexOf("."));
-        }
-        loadLib(fileNameWithoutExtension, true);
-      } catch (final Exception e) {
-        System.out.println("exception lading dll library " + e);
-        throw e;
-      }
-    }
-
-    for (int i = 0; i < managedDlls.length; i++) {
-      loadLib(managedDlls[i], true);
-    }
-  }
-
-  /**
-   * Puts library to temp dir and loads to memory
-   */
-
-  private static void loadLib(String name, final boolean copyOnly) {
-    name = name + DLL_EXTENSION;
-    //System.out.println("LOADING " + System.getProperty("user.dir") + "/reef/global/" + name );
-
-    try {
-      final String path = "/ReefDriverAppDlls/" + name;
-      //System.out.println("trying to load: " +  NativeInterop.class.getClass().getResource(path).getPath());
-      final InputStream in = NativeInterop.class.getResourceAsStream(path);
-      // always write to different location
-      final File fileOut = new File(tmpLoadingDirectory + LIB_BIN + name);
-      final OutputStream out = new FileOutputStream(fileOut);
-      //System.out.println("after new FileOutputStream(fileOut)");
-      if (null == in) {
-        // System.out.println("Cannot find " + path);
-        return;
-      }
-      if (out == null) {
-        System.out.println("** out is null");
-      }
-
-      IOUtils.copy(in, out);
-      in.close();
-      out.close();
-
-      if (false == copyOnly) {
-        //System.out.println("Loading DLL not copyonly");
-        System.load(fileOut.toString());
-        //System.out.println("Loading DLL not copyonly done");
-      } else {
-        //System.out.println("Loading DLL copyonly");
-        if (null == fileOut) {
-          System.out.println("fileOut is NULL");
-        }
-        //System.out.println("fileOut.toString() " + fileOut.toString());
-        NativeInterop.loadClrAssembly(fileOut.toString());
-        //System.out.println("Done Loading DLL " +  fileOut.toString());
-      }
-    } catch (final Exception e) {
-      throw new UnsatisfiedLinkError("Failed to load required DLL " + name);
-    }
-  }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/13cf5225/reef-bridge-project/reef-bridge-java/src/main/java/org/apache/reef/javabridge/generic/JobDriver.java
----------------------------------------------------------------------
diff --git a/reef-bridge-project/reef-bridge-java/src/main/java/org/apache/reef/javabridge/generic/JobDriver.java b/reef-bridge-project/reef-bridge-java/src/main/java/org/apache/reef/javabridge/generic/JobDriver.java
index adea40f..b2e0083 100644
--- a/reef-bridge-project/reef-bridge-java/src/main/java/org/apache/reef/javabridge/generic/JobDriver.java
+++ b/reef-bridge-project/reef-bridge-java/src/main/java/org/apache/reef/javabridge/generic/JobDriver.java
@@ -85,7 +85,17 @@ public final class JobDriver {
    * to request Evaluators that will run the Tasks.
    */
   private final EvaluatorRequestor evaluatorRequestor;
+
+  /**
+   * Driver status manager to monitor driver status
+   */
   private final DriverStatusManager driverStatusManager;
+
+  /**
+   *  NativeInterop has function to load libs when driver starts
+   */
+  private final LibLoader libLoader;
+
   /**
    * Shell execution results from each Evaluator.
    */
@@ -135,7 +145,8 @@ public final class JobDriver {
             final JobMessageObserver jobMessageObserver,
             final EvaluatorRequestor evaluatorRequestor,
             final DriverStatusManager driverStatusManager,
-            final LoggingScopeFactory loggingScopeFactory) {
+            final LoggingScopeFactory loggingScopeFactory,
+            final LibLoader libLoader) {
     this.clock = clock;
     this.httpServer = httpServer;
     this.jobMessageObserver = jobMessageObserver;
@@ -144,6 +155,7 @@ public final class JobDriver {
     this.driverStatusManager = driverStatusManager;
     this.nameServerInfo = NetUtils.getLocalAddress() + ":" + this.nameServer.getPort();
     this.loggingScopeFactory = loggingScopeFactory;
+    this.libLoader = libLoader;
   }
 
   private void setupBridge(final StartTime startTime) {
@@ -151,6 +163,13 @@ public final class JobDriver {
     // we can begin logging
     LOG.log(Level.INFO, "Initializing CLRBufferedLogHandler...");
     try (final LoggingScope lb = this.loggingScopeFactory.setupBridge()) {
+
+      try {
+        libLoader.loadLib();
+      } catch (IOException e) {
+        throw new RuntimeException("Fail to load CLR libraries");
+      }
+
       final CLRBufferedLogHandler handler = getCLRBufferedLogHandler();
       if (handler == null) {
         LOG.log(Level.WARNING, "CLRBufferedLogHandler could not be initialized");

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/13cf5225/reef-common/src/main/java/org/apache/reef/runtime/common/files/REEFFileNames.java
----------------------------------------------------------------------
diff --git a/reef-common/src/main/java/org/apache/reef/runtime/common/files/REEFFileNames.java b/reef-common/src/main/java/org/apache/reef/runtime/common/files/REEFFileNames.java
index a52346c..0fac287 100644
--- a/reef-common/src/main/java/org/apache/reef/runtime/common/files/REEFFileNames.java
+++ b/reef-common/src/main/java/org/apache/reef/runtime/common/files/REEFFileNames.java
@@ -47,6 +47,10 @@ public final class REEFFileNames {
   private static final String DRIVER_STDOUT = "driver.stdout";
   private static final String EVALUATOR_STDERR = "evaluator.stderr";
   private static final String EVALUATOR_STDOUT = "evaluator.stdout";
+  private static final String CPP_BRIDGE = "JavaClrBridge";
+  private static final String REEF_GLOBAL = "/reef/global";
+  private static final String REEF_DRIVER_APPDLL_DIR = "/ReefDriverAppDlls/";
+  private static final String TMP_LOAD_DIR = "/reef/CLRLoadingDirectory";
 
   @Inject
   public REEFFileNames() {
@@ -189,4 +193,24 @@ public final class REEFFileNames {
   public String getEvaluatorStdoutFileName() {
     return EVALUATOR_STDOUT;
   }
+
+  /**
+   * @return the name of cpp bridge file
+   */
+  public String getCppBridge() { return CPP_BRIDGE; }
+
+  /**
+   * @return reeg global file folder
+   */
+  public String getReefGlobal() { return REEF_GLOBAL; }
+
+  /**
+   * @return reef driver app dll directory
+   */
+  public String getReefDriverAppDllDir() { return REEF_DRIVER_APPDLL_DIR; }
+
+  /**
+   * @return temp load directory
+   */
+  public String getLoadDir() { return TMP_LOAD_DIR; }
 }

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/13cf5225/reef-common/src/main/java/org/apache/reef/util/logging/LoggingScopeFactory.java
----------------------------------------------------------------------
diff --git a/reef-common/src/main/java/org/apache/reef/util/logging/LoggingScopeFactory.java b/reef-common/src/main/java/org/apache/reef/util/logging/LoggingScopeFactory.java
index 31210bc..6f4bc54 100644
--- a/reef-common/src/main/java/org/apache/reef/util/logging/LoggingScopeFactory.java
+++ b/reef-common/src/main/java/org/apache/reef/util/logging/LoggingScopeFactory.java
@@ -37,6 +37,7 @@ public class LoggingScopeFactory {
   public static final String DRIVER_START = "Driver Start Handler";
   public static final String DRIVER_STOP = "Driver Stop Handler";
   public static final String BRIDGE_SETUP = "Bridge setup";
+  public static final String LOAD_LIB = "Load libraries";
   public static final String EVALUATOR_REQUESTOR = "Evaluator requestor passed to C#";
   public static final String EVALUATOR_BRIDGE_SUBMIT = "Evaluator request submit cross bridge";
   public static final String EVALUATOR_SUBMIT = "Evaluator submit";
@@ -130,6 +131,14 @@ public class LoggingScopeFactory {
   }
 
   /**
+   * The method is to measure the time used to load global files and libraries
+   * @return
+   */
+  public LoggingScope loadLib() {
+    return new LoggingScopeImpl(LOG, logLevel, LOAD_LIB);
+  }
+
+  /**
    * The method is to measure the time used to pass EvaluatorRequestor from Java to .Net. It can be inserted to the code between beginning to send EvaluatorRequestor to CLR until it is returned.
    * @return
    */