You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by tk...@apache.org on 2017/04/06 03:09:58 UTC

nifi git commit: NIFI-3586: Fix for retrieving ProcessID for NiFi under windows.

Repository: nifi
Updated Branches:
  refs/heads/master f5f54c468 -> 3386839eb


NIFI-3586: Fix for retrieving ProcessID for NiFi under windows.

This closes #1586

Signed-off-by: Tony Kurc <tk...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/3386839e
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/3386839e
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/3386839e

Branch: refs/heads/master
Commit: 3386839ebc4a16029fc40a1b2702017b1ab39fa3
Parents: f5f54c4
Author: Puspendu Banerjee <Pu...@gmail.com>
Authored: Fri Mar 10 15:09:49 2017 -0600
Committer: Tony Kurc <tr...@gmail.com>
Committed: Wed Apr 5 23:09:48 2017 -0400

----------------------------------------------------------------------
 nifi-assembly/LICENSE                           |  25 ++++-
 nifi-assembly/NOTICE                            |   6 ++
 nifi-bootstrap/pom.xml                          |   5 +
 .../java/org/apache/nifi/bootstrap/RunNiFi.java |  28 +----
 .../org/apache/nifi/bootstrap/util/OSUtils.java | 107 +++++++++++++++++++
 5 files changed, 147 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/3386839e/nifi-assembly/LICENSE
----------------------------------------------------------------------
diff --git a/nifi-assembly/LICENSE b/nifi-assembly/LICENSE
index edfd806..be2b667 100644
--- a/nifi-assembly/LICENSE
+++ b/nifi-assembly/LICENSE
@@ -1838,4 +1838,27 @@ under an MIT style license.  For details see https://github.com/OfficeDev/ews-ja
     AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-    THE SOFTWARE.
\ No newline at end of file
+    THE SOFTWARE.
+
+This product bundles 'libffi' which is available under an MIT style license.
+    libffi - Copyright (c) 1996-2014  Anthony Green, Red Hat, Inc and others.
+	see https://github.com/java-native-access/jna/blob/master/native/libffi/LICENSE
+
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files (the
+	``Software''), to deal in the Software without restriction, including
+	without limitation the rights to use, copy, modify, merge, publish,
+	distribute, sublicense, and/or sell copies of the Software, and to
+	permit persons to whom the Software is furnished to do so, subject to
+	the following conditions:
+
+	The above copyright notice and this permission notice shall be
+	included in all copies or substantial portions of the Software.
+
+	THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+	CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+	TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

http://git-wip-us.apache.org/repos/asf/nifi/blob/3386839e/nifi-assembly/NOTICE
----------------------------------------------------------------------
diff --git a/nifi-assembly/NOTICE b/nifi-assembly/NOTICE
index e5db477..5b4c449 100644
--- a/nifi-assembly/NOTICE
+++ b/nifi-assembly/NOTICE
@@ -374,6 +374,11 @@ The following binary components are provided under the Apache Software License v
       Apache Commons Math
       Copyright 2001-2012 The Apache Software Foundation
 
+  (ASLv2) Java Native Access Platform
+    The following NOTICE information applies:
+      Java Native Access Platform
+      Copyright 2013 Timothy Wall, Matthias Bl�sing
+
       This product includes software developed by
       The Apache Software Foundation (http://www.apache.org/).
 
@@ -1298,6 +1303,7 @@ The MIT License
 The following binary components are provided under the MIT License.  See project link for details.
 
   (MIT License) EWS Java API (com.microsoft.ews-java-api:ews-java-api:2.0 - https://github.com/OfficeDev/ews-java-api)
+  (MIT License) libffi (libffi-3.2.1 - http://sourceware.org/libffi/)
 
 *****************
 Mozilla Public License v2.0

http://git-wip-us.apache.org/repos/asf/nifi/blob/3386839e/nifi-bootstrap/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-bootstrap/pom.xml b/nifi-bootstrap/pom.xml
index 998392e..db0645d 100644
--- a/nifi-bootstrap/pom.xml
+++ b/nifi-bootstrap/pom.xml
@@ -47,5 +47,10 @@ language governing permissions and limitations under the License. -->
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-properties-loader</artifactId>
         </dependency>
+        <dependency>
+            <groupId>net.java.dev.jna</groupId>
+		    <artifactId>jna-platform</artifactId>
+		    <version>4.4.0</version>
+		</dependency>
     </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/nifi/blob/3386839e/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/RunNiFi.java
----------------------------------------------------------------------
diff --git a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/RunNiFi.java b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/RunNiFi.java
index 10d5cde..edca894 100644
--- a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/RunNiFi.java
+++ b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/RunNiFi.java
@@ -27,7 +27,6 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.Reader;
-import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
@@ -55,6 +54,7 @@ import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.bootstrap.notification.NotificationType;
+import org.apache.nifi.bootstrap.util.OSUtils;
 import org.apache.nifi.util.file.FileUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -1066,9 +1066,9 @@ public class RunNiFi {
 
         Process process = builder.start();
         handleLogging(process);
-        Long pid = getPid(process, cmdLogger);
+        Long pid = OSUtils.getProcessId(process, cmdLogger);
         if (pid == null) {
-            cmdLogger.info("Launched Apache NiFi but could not determined the Process ID");
+            cmdLogger.warn("Launched Apache NiFi but could not determined the Process ID");
         } else {
             nifiPid = pid;
             final Properties pidProperties = new Properties();
@@ -1131,9 +1131,9 @@ public class RunNiFi {
                     process = builder.start();
                     handleLogging(process);
 
-                    pid = getPid(process, defaultLogger);
+                    pid = OSUtils.getProcessId(process, defaultLogger);
                     if (pid == null) {
-                        cmdLogger.info("Launched Apache NiFi but could not obtain the Process ID");
+                        cmdLogger.warn("Launched Apache NiFi but could not obtain the Process ID");
                     } else {
                         nifiPid = pid;
                         final Properties pidProperties = new Properties();
@@ -1214,24 +1214,6 @@ public class RunNiFi {
         this.loggingFutures = futures;
     }
 
-    private Long getPid(final Process process, final Logger logger) {
-        try {
-            final Class<?> procClass = process.getClass();
-            final Field pidField = procClass.getDeclaredField("pid");
-            pidField.setAccessible(true);
-            final Object pidObject = pidField.get(process);
-
-            logger.debug("PID Object = {}", pidObject);
-
-            if (pidObject instanceof Number) {
-                return ((Number) pidObject).longValue();
-            }
-            return null;
-        } catch (final IllegalAccessException | NoSuchFieldException nsfe) {
-            logger.debug("Could not find PID for child process due to {}", nsfe);
-            return null;
-        }
-    }
 
     private boolean isWindows() {
         final String osName = System.getProperty("os.name");

http://git-wip-us.apache.org/repos/asf/nifi/blob/3386839e/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/util/OSUtils.java
----------------------------------------------------------------------
diff --git a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/util/OSUtils.java b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/util/OSUtils.java
new file mode 100644
index 0000000..23b512a
--- /dev/null
+++ b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/util/OSUtils.java
@@ -0,0 +1,107 @@
+/*
+ * 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.nifi.bootstrap.util;
+
+import java.lang.reflect.Field;
+
+import org.slf4j.Logger;
+import com.sun.jna.Pointer;
+import com.sun.jna.platform.win32.Kernel32;
+import com.sun.jna.platform.win32.WinNT;
+
+/**
+ * OS specific utilities with generic method interfaces
+ */
+public final class OSUtils {
+    /**
+     * @param process NiFi Process Reference
+     * @param logger  Logger Reference for Debug
+     * @return        Returns pid or null in-case pid could not be determined
+     * This method takes {@link Process} and {@link Logger} and returns
+     * the platform specific ProcessId for Unix like systems, a.k.a <b>pid</b>
+     * In-case it fails to determine the pid, it will return Null.
+     * Purpose for the Logger is to log any interaction for debugging.
+     */
+    private static Long getUnicesPid(final Process process, final Logger logger) {
+        try {
+            final Class<?> procClass = process.getClass();
+            final Field pidField = procClass.getDeclaredField("pid");
+            pidField.setAccessible(true);
+            final Object pidObject = pidField.get(process);
+
+            logger.debug("PID Object = {}", pidObject);
+
+            if (pidObject instanceof Number) {
+                return ((Number) pidObject).longValue();
+            }
+            return null;
+        } catch (final IllegalAccessException | NoSuchFieldException nsfe) {
+            logger.debug("Could not find PID for child process due to {}", nsfe);
+            return null;
+        }
+    }
+
+    /**
+     * @param process NiFi Process Reference
+     * @param logger  Logger Reference for Debug
+     * @return        Returns pid or null in-case pid could not be determined
+     * This method takes {@link Process} and {@link Logger} and returns
+     * the platform specific Handle for Win32 Systems, a.k.a <b>pid</b>
+     * In-case it fails to determine the pid, it will return Null.
+     * Purpose for the Logger is to log any interaction for debugging.
+     */
+    private static Long getWindowsProcessId(final Process process, final Logger logger) {
+        /* determine the pid on windows plattforms */
+        try {
+            Field f = process.getClass().getDeclaredField("handle");
+            f.setAccessible(true);
+            long handl = f.getLong(process);
+
+            Kernel32 kernel = Kernel32.INSTANCE;
+            WinNT.HANDLE handle = new WinNT.HANDLE();
+            handle.setPointer(Pointer.createConstant(handl));
+            int ret = kernel.GetProcessId(handle);
+            logger.debug("Detected pid: {}", ret);
+            return Long.valueOf(ret);
+        } catch (final IllegalAccessException | NoSuchFieldException nsfe) {
+            logger.debug("Could not find PID for child process due to {}", nsfe);
+        }
+        return null;
+    }
+
+    /**
+     * @param process NiFi Process Reference
+     * @param logger  Logger Reference for Debug
+     * @return        Returns pid or null in-case pid could not be determined
+     * This method takes {@link Process} and {@link Logger} and returns
+     * the platform specific ProcessId for Unix like systems or Handle for Win32 Systems, a.k.a <b>pid</b>
+     * In-case it fails to determine the pid, it will return Null.
+     * Purpose for the Logger is to log any interaction for debugging.
+     */
+    public static Long getProcessId(final Process process, final Logger logger) {
+        if (process.getClass().getName().equals("java.lang.UNIXProcess")) {
+            return getUnicesPid(process, logger);
+        } else if (process.getClass().getName().equals("java.lang.Win32Process")
+                || process.getClass().getName().equals("java.lang.ProcessImpl")) {
+            return getWindowsProcessId(process, logger);
+        }
+
+        return null;
+    }
+
+}