You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by gh...@apache.org on 2020/06/30 09:27:44 UTC

[felix-dev] branch master updated (4fe02a6 -> 28fc43b)

This is an automated email from the ASF dual-hosted git repository.

ghenzler pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/felix-dev.git.


    from 4fe02a6  Merge pull request #27 from tjwatson/FELIX-6274
     new d53c738  FELIX-6289 Make Servlet API optional
     new 28fc43b  FELIX-6246 Remove dependency to commons lang

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 healthcheck/core/bnd.bnd                           |  5 +-
 healthcheck/core/pom.xml                           | 23 +++---
 .../core/impl/JmxAdjustableStatusHealthCheck.java  |  8 +-
 .../impl/executor/HealthCheckExecutorImpl.java     | 10 +--
 .../hc/core/impl/executor/HealthCheckFuture.java   | 90 +++++++++++++---------
 .../executor/async/AsyncHealthCheckExecutor.java   |  5 +-
 .../AdhocResultDuringRequestProcessingFilter.java  |  2 +-
 .../core/impl/filter/ServiceUnavailableFilter.java |  4 +-
 .../hc/core/impl/monitor/HealthCheckMonitor.java   |  4 +-
 .../impl/servlet/HealthCheckExecutorServlet.java   | 52 ++++++-------
 .../hc/core/impl/servlet/ResultHtmlSerializer.java | 41 +++++++---
 .../hc/core/impl/servlet/ResultJsonSerializer.java |  2 +-
 .../impl/servlet/ResultTxtVerboseSerializer.java   | 50 +++++++++---
 .../felix/hc/core/impl/util/lang/StringUtils.java  | 52 +++++++++++++
 .../felix/hc/jmx/impl/HealthCheckMBeanCreator.java |  2 +-
 .../servlet/HealthCheckExecutorServletTest.java    |  6 +-
 .../servlet/ResultTxtVerboseSerializerTest.java    | 39 ++++++++++
 .../felix/hc/core/impl/util/StringUtilsTest.java}  | 34 ++++----
 .../test/java/org/apache/felix/hc/core/it/U.java   |  1 -
 healthcheck/generalchecks/bnd.bnd                  |  2 +-
 healthcheck/generalchecks/pom.xml                  | 14 ++--
 .../hc/generalchecks/BundlesStartedCheck.java      |  2 +-
 .../felix/hc/generalchecks/DsComponentsCheck.java  |  5 +-
 .../hc/generalchecks/FrameworkStartCheck.java      |  2 +-
 .../felix/hc/generalchecks/HttpRequestsCheck.java  | 32 +++++---
 .../felix/hc/generalchecks/JmxAttributeCheck.java  |  4 +-
 .../hc/generalchecks/ScriptedHealthCheck.java      |  2 +-
 .../felix/hc/generalchecks/util/ScriptHelper.java  |  2 +-
 .../util/SimpleConstraintChecker.java              | 30 +++++---
 healthcheck/webconsoleplugin/pom.xml               | 13 +---
 .../impl/HealthCheckWebconsolePlugin.java          | 18 +++--
 .../felix/hc/webconsole/impl/WebConsoleHelper.java | 16 ++--
 32 files changed, 367 insertions(+), 205 deletions(-)
 create mode 100644 healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/util/lang/StringUtils.java
 create mode 100644 healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/servlet/ResultTxtVerboseSerializerTest.java
 copy healthcheck/{api/src/test/java/org/apache/felix/hc/api/FormattingResultLogTest.java => core/src/test/java/org/apache/felix/hc/core/impl/util/StringUtilsTest.java} (50%)


[felix-dev] 01/02: FELIX-6289 Make Servlet API optional

Posted by gh...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ghenzler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/felix-dev.git

commit d53c738140e14a9ce34e374169e125f2403e3321
Author: georg.henzler <ge...@netcentric.biz>
AuthorDate: Tue Jun 30 08:42:21 2020 +0200

    FELIX-6289 Make Servlet API optional
---
 healthcheck/core/bnd.bnd | 5 ++++-
 healthcheck/core/pom.xml | 2 ++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/healthcheck/core/bnd.bnd b/healthcheck/core/bnd.bnd
index 44ae747..ceba184 100644
--- a/healthcheck/core/bnd.bnd
+++ b/healthcheck/core/bnd.bnd
@@ -8,7 +8,10 @@ Bundle-License: Apache License, Version 2.0
 
 Bundle-Vendor: The Apache Software Foundation
 
-Import-Package: org.quartz*;resolution:="optional", *
+Import-Package:\
+  org.quartz*;resolution:=optional,\
+  javax.servlet*;resolution:=optional,\
+  *
 
 Conditional-Package: org.apache.felix.utils.*
 
diff --git a/healthcheck/core/pom.xml b/healthcheck/core/pom.xml
index 6363f32..283cb73 100644
--- a/healthcheck/core/pom.xml
+++ b/healthcheck/core/pom.xml
@@ -177,6 +177,8 @@
             <artifactId>javax.servlet-api</artifactId>
             <version>3.1.0</version>
             <scope>provided</scope>
+            <!-- servlet api optional: only add configs for servlets/filters your setup includes the servlet runtime! -->
+            <optional>true</optional>
         </dependency>
 
         <!-- used for JSONWriter, included in bundle via Conditional-Package -->


[felix-dev] 02/02: FELIX-6246 Remove dependency to commons lang

Posted by gh...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ghenzler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/felix-dev.git

commit 28fc43b766216cfacda5460e0151bc780801a136
Author: georg.henzler <ge...@netcentric.biz>
AuthorDate: Tue Jun 30 11:21:33 2020 +0200

    FELIX-6246 Remove dependency to commons lang
---
 healthcheck/core/pom.xml                           | 23 ++----
 .../core/impl/JmxAdjustableStatusHealthCheck.java  |  8 +-
 .../impl/executor/HealthCheckExecutorImpl.java     | 10 +--
 .../hc/core/impl/executor/HealthCheckFuture.java   | 90 +++++++++++++---------
 .../executor/async/AsyncHealthCheckExecutor.java   |  5 +-
 .../AdhocResultDuringRequestProcessingFilter.java  |  2 +-
 .../core/impl/filter/ServiceUnavailableFilter.java |  4 +-
 .../hc/core/impl/monitor/HealthCheckMonitor.java   |  4 +-
 .../impl/servlet/HealthCheckExecutorServlet.java   | 52 ++++++-------
 .../hc/core/impl/servlet/ResultHtmlSerializer.java | 41 +++++++---
 .../hc/core/impl/servlet/ResultJsonSerializer.java |  2 +-
 .../impl/servlet/ResultTxtVerboseSerializer.java   | 50 +++++++++---
 .../felix/hc/core/impl/util/lang/StringUtils.java  | 52 +++++++++++++
 .../felix/hc/jmx/impl/HealthCheckMBeanCreator.java |  2 +-
 .../servlet/HealthCheckExecutorServletTest.java    |  6 +-
 .../servlet/ResultTxtVerboseSerializerTest.java    | 39 ++++++++++
 .../felix/hc/core/impl/util/StringUtilsTest.java   | 46 +++++++++++
 .../test/java/org/apache/felix/hc/core/it/U.java   |  1 -
 healthcheck/generalchecks/bnd.bnd                  |  2 +-
 healthcheck/generalchecks/pom.xml                  | 14 ++--
 .../hc/generalchecks/BundlesStartedCheck.java      |  2 +-
 .../felix/hc/generalchecks/DsComponentsCheck.java  |  5 +-
 .../hc/generalchecks/FrameworkStartCheck.java      |  2 +-
 .../felix/hc/generalchecks/HttpRequestsCheck.java  | 32 +++++---
 .../felix/hc/generalchecks/JmxAttributeCheck.java  |  4 +-
 .../hc/generalchecks/ScriptedHealthCheck.java      |  2 +-
 .../felix/hc/generalchecks/util/ScriptHelper.java  |  2 +-
 .../util/SimpleConstraintChecker.java              | 30 +++++---
 healthcheck/webconsoleplugin/pom.xml               | 13 +---
 .../impl/HealthCheckWebconsolePlugin.java          | 18 +++--
 .../felix/hc/webconsole/impl/WebConsoleHelper.java | 16 ++--
 31 files changed, 390 insertions(+), 189 deletions(-)

diff --git a/healthcheck/core/pom.xml b/healthcheck/core/pom.xml
index 283cb73..08aabb3 100644
--- a/healthcheck/core/pom.xml
+++ b/healthcheck/core/pom.xml
@@ -157,27 +157,20 @@
         </dependency>
 
         <dependency>
-            <groupId>org.apache.servicemix.bundles</groupId>
-            <artifactId>org.apache.servicemix.bundles.quartz</artifactId>
-            <version>2.3.0_2</version>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <version>3.1.0</version>
             <scope>provided</scope>
-            <!-- if not present in runtime, there is no support for async health checks -->
+            <!-- servlet api optional: only add configs for servlets/filters your setup includes the servlet runtime! -->
             <optional>true</optional>
         </dependency>
 
         <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-lang3</artifactId>
-            <version>3.4</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>javax.servlet</groupId>
-            <artifactId>javax.servlet-api</artifactId>
-            <version>3.1.0</version>
+            <groupId>org.apache.servicemix.bundles</groupId>
+            <artifactId>org.apache.servicemix.bundles.quartz</artifactId>
+            <version>2.3.0_2</version>
             <scope>provided</scope>
-            <!-- servlet api optional: only add configs for servlets/filters your setup includes the servlet runtime! -->
+            <!-- if not present in runtime, there is no support for async health checks -->
             <optional>true</optional>
         </dependency>
 
diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/JmxAdjustableStatusHealthCheck.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/JmxAdjustableStatusHealthCheck.java
index ed1c403..c9895e3 100644
--- a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/JmxAdjustableStatusHealthCheck.java
+++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/JmxAdjustableStatusHealthCheck.java
@@ -34,8 +34,6 @@ import javax.management.MBeanInfo;
 import javax.management.MBeanOperationInfo;
 import javax.management.MBeanParameterInfo;
 import javax.management.ReflectionException;
-
-import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.hc.api.HealthCheck;
 import org.apache.felix.hc.api.Result;
 import org.apache.felix.hc.api.Result.Status;
@@ -136,7 +134,7 @@ public class JmxAdjustableStatusHealthCheck {
         public Object getAttribute(final String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException {
 
             if (ATT_TAGS.equals(attribute)) {
-                return StringUtils.join(tags, ",");
+                return String.join(",", tags);
             } else if (ATT_STATUS.equals(attribute)) {
                 return status.toString();
             } else {
@@ -212,9 +210,9 @@ public class JmxAdjustableStatusHealthCheck {
             
             status = newStatus.toString();
             registerDynamicHealthCheck(newStatus, tags.toArray(new String[tags.size()]));
-            LOG.info("Activated JMX-adjustable Health Check with status "+newStatus+" and tags " + StringUtils.join(tags, ","));
+            LOG.info("Activated JMX-adjustable Health Check with status "+newStatus+" and tags " + String.join(",", tags));
             return "Added check with result "+newStatus;
-        
+
         }
 
         @Override
diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/HealthCheckExecutorImpl.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/HealthCheckExecutorImpl.java
index 2c400e1..e0aa7f4 100644
--- a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/HealthCheckExecutorImpl.java
+++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/HealthCheckExecutorImpl.java
@@ -38,8 +38,6 @@ import java.util.ListIterator;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.commons.lang3.ArrayUtils;
-import org.apache.commons.lang3.time.StopWatch;
 import org.apache.felix.hc.api.FormattingResultLog;
 import org.apache.felix.hc.api.HealthCheck;
 import org.apache.felix.hc.api.Result;
@@ -174,7 +172,7 @@ public class HealthCheckExecutorImpl implements ExtendedHealthCheckExecutor, Ser
     public List<HealthCheckExecutionResult> execute(HealthCheckSelector selector, HealthCheckExecutionOptions options) {
         logger.debug("Starting executing checks for filter selector {} and execution options {}", selector, options);
 
-        if (ArrayUtils.isEmpty(selector.tags())) {
+        if (selector.tags() == null || selector.tags().length == 0) {
             logger.debug("Using default tags");
             selector.withTags(defaultTags);
         }
@@ -366,8 +364,8 @@ public class HealthCheckExecutorImpl implements ExtendedHealthCheckExecutor, Ser
     /** Wait for the futures until the timeout is reached */
     private void waitForFuturesRespectingTimeout(final List<HealthCheckFuture> futuresForResultOfThisCall,
             HealthCheckExecutionOptions options) {
-        final StopWatch callExcutionTimeStopWatch = new StopWatch();
-        callExcutionTimeStopWatch.start();
+        
+        final long callExcutionStartTime = System.currentTimeMillis();
         boolean allFuturesDone;
 
         long effectiveTimeout = this.timeoutInMs;
@@ -392,7 +390,7 @@ public class HealthCheckExecutorImpl implements ExtendedHealthCheckExecutor, Ser
             for (final HealthCheckFuture healthCheckFuture : futuresForResultOfThisCall) {
                 allFuturesDone &= healthCheckFuture.isDone();
             }
-        } while (!allFuturesDone && callExcutionTimeStopWatch.getTime() < effectiveTimeout);
+        } while (!allFuturesDone && (System.currentTimeMillis() - callExcutionStartTime) < effectiveTimeout);
     }
 
     /** Collect the results from all futures
diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/HealthCheckFuture.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/HealthCheckFuture.java
index 937eec9..d86409a 100644
--- a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/HealthCheckFuture.java
+++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/HealthCheckFuture.java
@@ -19,15 +19,13 @@ package org.apache.felix.hc.core.impl.executor;
 
 import static org.apache.felix.hc.api.FormattingResultLog.msHumanReadable;
 
-import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
 import java.util.Date;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.FutureTask;
 
-import org.apache.commons.lang3.reflect.FieldUtils;
-import org.apache.commons.lang3.reflect.MethodUtils;
-import org.apache.commons.lang3.time.StopWatch;
 import org.apache.felix.hc.api.FormattingResultLog;
 import org.apache.felix.hc.api.HealthCheck;
 import org.apache.felix.hc.api.Result;
@@ -57,19 +55,18 @@ public class HealthCheckFuture extends FutureTask<ExecutionResult> {
                 Thread.currentThread().setName("HealthCheck " + metadata.getTitle());
                 LOG.debug("Starting check {}", metadata);
 
-                final StopWatch stopWatch = new StopWatch();
-                stopWatch.start();
+                long startTime = System.currentTimeMillis();
                 Result resultFromHealthCheck = null;
                 ExecutionResult executionResult = null;
 
-                Object healthCheck = bundleContext.getService(metadata.getServiceReference());
+                Object healthCheckObject = bundleContext.getService(metadata.getServiceReference());
                 try {
-                    if (healthCheck != null) {
-                        if ((healthCheck instanceof HealthCheck)) {
-                            resultFromHealthCheck = ((HealthCheck) healthCheck).execute();
-                        } else {
-                            resultFromHealthCheck = executeLegacyHc(healthCheck);
-                        }
+                    if (healthCheckObject != null) {
+                        HealthCheck healthCheck = healthCheckObject instanceof HealthCheck 
+                                ? (HealthCheck) healthCheckObject 
+                                : new LegacyHealthCheckWrapper(healthCheckObject);
+                        resultFromHealthCheck = healthCheck.execute();
+
                     } else {
                         throw new IllegalStateException("Service cannot be retrieved - probably activate() failed or there are unsatisfied references");
                     }
@@ -82,8 +79,7 @@ public class HealthCheckFuture extends FutureTask<ExecutionResult> {
                     bundleContext.ungetService(metadata.getServiceReference());
 
                     // update result with information about this run
-                    stopWatch.stop();
-                    long elapsedTime = stopWatch.getTime();
+                    long elapsedTime = (System.currentTimeMillis() - startTime);
                     if (resultFromHealthCheck != null) {
                         // wrap the result in an execution result
                         executionResult = new ExecutionResult(metadata, resultFromHealthCheck, elapsedTime);
@@ -115,31 +111,49 @@ public class HealthCheckFuture extends FutureTask<ExecutionResult> {
         return "[Future for " + this.metadata + ", createdTime=" + this.createdTime + "]";
     }
 
-    @SuppressWarnings("rawtypes")
-    private static Result executeLegacyHc(Object healthCheck) {
-
-        FormattingResultLog log = new FormattingResultLog();
-        log.debug("Running legacy HC {}, please convert to new interface org.apache.felix.hc.api.HealthCheck!",
-                healthCheck.getClass().getName());
-        try {
-            Object result = MethodUtils.invokeMethod(healthCheck, "execute");
-            Object resultLog = FieldUtils.readField(result, "resultLog", true);
-
-            List entries = (List) FieldUtils.readField(resultLog, "entries", true);
-            for (Object object : entries) {
-                String statusLegacy = String.valueOf(FieldUtils.readField(object, "status", true));
-                String message = (String) FieldUtils.readField(object, "message", true);
-                Exception exception = (Exception) FieldUtils.readField(object, "exception", true);
-                if(statusLegacy.equals("DEBUG")) {
-                    log.add(new ResultLog.Entry(message, true, exception));
-                } else {
-                    statusLegacy = statusLegacy.replace("INFO", "OK");
-                    log.add(new ResultLog.Entry(Result.Status.valueOf(statusLegacy), message, exception));
+    private static class LegacyHealthCheckWrapper implements HealthCheck {
+        private final Object legacyHealthCheck;
+        private final FormattingResultLog log;
+        
+        public LegacyHealthCheckWrapper(Object legacyHealthCheck) {
+            this.legacyHealthCheck = legacyHealthCheck;
+            this.log = new FormattingResultLog();
+        }
+
+        @Override
+        @SuppressWarnings("rawtypes")
+        public Result execute() {
+            Class<?> hcClass = legacyHealthCheck.getClass();
+            log.debug("Running legacy HC {}, please convert to new interface org.apache.felix.hc.api.HealthCheck!",
+                    hcClass.getName());
+            try {
+                Method executeMethod = hcClass.getMethod("execute");
+                Object result = executeMethod.invoke(legacyHealthCheck);
+                Object resultLog = readPrivateField(result, "resultLog");
+
+                List<?> entries = (List) readPrivateField(resultLog, "entries");
+                for (Object object : entries) {
+                    String statusLegacy = String.valueOf(readPrivateField(object, "status"));
+                    String message = (String) readPrivateField(object, "message");
+                    Exception exception = (Exception) readPrivateField(object, "exception");
+                    if(statusLegacy.equals("DEBUG")) {
+                        log.add(new ResultLog.Entry(message, true, exception));
+                    } else {
+                        statusLegacy = statusLegacy.replace("INFO", Result.Status.OK.name());
+                        log.add(new ResultLog.Entry(Result.Status.valueOf(statusLegacy), message, exception));
+                    }
                 }
+            } catch (ReflectiveOperationException e) {
+                log.healthCheckError("Could call and convert Sling HC {} for Felix Runtime", hcClass.getName());
             }
-        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
-            log.healthCheckError("Could call and convert Sling HC {} for Felix Runtime", healthCheck.getClass().getName());
+            return new Result(log);
+        }
+        
+        private Object readPrivateField(Object target, String fieldName) throws ReflectiveOperationException {
+            Field field = target.getClass().getDeclaredField(fieldName);
+            field.setAccessible(true);
+            return field.get(target);
         }
-        return new Result(log);
     }
+
 }
diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/async/AsyncHealthCheckExecutor.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/async/AsyncHealthCheckExecutor.java
index 11ff1e2..bf2f86b 100644
--- a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/async/AsyncHealthCheckExecutor.java
+++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/async/AsyncHealthCheckExecutor.java
@@ -27,7 +27,6 @@ import java.util.Set;
 import java.util.TreeSet;
 import java.util.concurrent.ConcurrentHashMap;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.hc.api.HealthCheck;
 import org.apache.felix.hc.api.Result;
 import org.apache.felix.hc.api.execution.HealthCheckExecutionResult;
@@ -38,12 +37,12 @@ import org.apache.felix.hc.core.impl.executor.HealthCheckExecutorThreadPool;
 import org.apache.felix.hc.core.impl.executor.HealthCheckFuture;
 import org.apache.felix.hc.core.impl.executor.HealthCheckFuture.Callback;
 import org.apache.felix.hc.core.impl.executor.HealthCheckResultCache;
-import org.apache.felix.hc.core.impl.scheduling.AsyncQuartzCronJob;
 import org.apache.felix.hc.core.impl.scheduling.AsyncIntervalJob;
 import org.apache.felix.hc.core.impl.scheduling.AsyncJob;
-import org.apache.felix.hc.core.impl.scheduling.QuartzCronScheduler;
+import org.apache.felix.hc.core.impl.scheduling.AsyncQuartzCronJob;
 import org.apache.felix.hc.core.impl.scheduling.QuartzCronSchedulerProvider;
 import org.apache.felix.hc.core.impl.util.HealthCheckFilter;
+import org.apache.felix.hc.core.impl.util.lang.StringUtils;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceEvent;
diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/filter/AdhocResultDuringRequestProcessingFilter.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/filter/AdhocResultDuringRequestProcessingFilter.java
index e0a22a4..4184ff6 100644
--- a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/filter/AdhocResultDuringRequestProcessingFilter.java
+++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/filter/AdhocResultDuringRequestProcessingFilter.java
@@ -32,7 +32,6 @@ import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.hc.api.HealthCheck;
 import org.apache.felix.hc.api.Result;
 import org.apache.felix.hc.api.execution.HealthCheckExecutionOptions;
@@ -42,6 +41,7 @@ import org.apache.felix.hc.api.execution.HealthCheckSelector;
 import org.apache.felix.hc.core.impl.executor.CombinedExecutionResult;
 import org.apache.felix.hc.core.impl.servlet.ResultTxtVerboseSerializer;
 import org.apache.felix.hc.core.impl.util.AdhocStatusHealthCheck;
+import org.apache.felix.hc.core.impl.util.lang.StringUtils;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.component.ComponentContext;
diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/filter/ServiceUnavailableFilter.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/filter/ServiceUnavailableFilter.java
index 977dc3d..7d7161c 100644
--- a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/filter/ServiceUnavailableFilter.java
+++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/filter/ServiceUnavailableFilter.java
@@ -40,7 +40,6 @@ import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.hc.api.HealthCheck;
 import org.apache.felix.hc.api.Result;
 import org.apache.felix.hc.api.execution.HealthCheckExecutionOptions;
@@ -49,6 +48,7 @@ import org.apache.felix.hc.api.execution.HealthCheckSelector;
 import org.apache.felix.hc.core.impl.executor.CombinedExecutionResult;
 import org.apache.felix.hc.core.impl.executor.ExtendedHealthCheckExecutor;
 import org.apache.felix.hc.core.impl.servlet.ResultTxtVerboseSerializer;
+import org.apache.felix.hc.core.impl.util.lang.StringUtils;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
@@ -189,7 +189,7 @@ public class ServiceUnavailableFilter implements Filter {
         if(StringUtils.isBlank(responseFor503)) {
             responseFor503 = (String) compProperties.get("htmlFor503"); // backwards-compatibility
         }
-        if(StringUtils.startsWith(responseFor503, CLASSPATH_PREFIX)) {
+        if(responseFor503 != null && responseFor503.startsWith(CLASSPATH_PREFIX)) {
             String[] bits = responseFor503.split(":");
             String symbolicName = bits[1];
             String pathInBundle = bits[2];
diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/monitor/HealthCheckMonitor.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/monitor/HealthCheckMonitor.java
index f687d68..36ce295 100644
--- a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/monitor/HealthCheckMonitor.java
+++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/monitor/HealthCheckMonitor.java
@@ -27,7 +27,6 @@ import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.hc.api.Result;
 import org.apache.felix.hc.api.condition.Healthy;
 import org.apache.felix.hc.api.condition.SystemReady;
@@ -41,6 +40,7 @@ import org.apache.felix.hc.core.impl.scheduling.AsyncIntervalJob;
 import org.apache.felix.hc.core.impl.scheduling.AsyncJob;
 import org.apache.felix.hc.core.impl.scheduling.AsyncQuartzCronJob;
 import org.apache.felix.hc.core.impl.scheduling.QuartzCronSchedulerProvider;
+import org.apache.felix.hc.core.impl.util.lang.StringUtils;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceRegistration;
@@ -288,7 +288,7 @@ public class HealthCheckMonitor implements Runnable {
                 registrationProps.put(propertyName, tagOrName);
                 registrationProps.put("activated", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
 
-                if (StringUtils.equals(tagOrName, TAG_SYSTEMREADY)) {
+                if (TAG_SYSTEMREADY.equals(tagOrName)) {
                     LOG.debug("HealthCheckMonitor: SYSTEM READY");
                     healthyRegistration = bundleContext.registerService(
                             new String[] { SystemReady.class.getName(), Healthy.class.getName() },
diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServlet.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServlet.java
index 73a3285..b5abc76 100644
--- a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServlet.java
+++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServlet.java
@@ -31,14 +31,13 @@ import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.apache.commons.lang3.StringEscapeUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.hc.api.Result;
 import org.apache.felix.hc.api.execution.HealthCheckExecutionOptions;
 import org.apache.felix.hc.api.execution.HealthCheckExecutionResult;
 import org.apache.felix.hc.api.execution.HealthCheckExecutor;
 import org.apache.felix.hc.api.execution.HealthCheckSelector;
 import org.apache.felix.hc.core.impl.executor.CombinedExecutionResult;
+import org.apache.felix.hc.core.impl.util.lang.StringUtils;
 import org.osgi.service.component.ComponentContext;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
@@ -226,11 +225,10 @@ public class HealthCheckExecutorServlet extends HttpServlet {
         this.servletPaths = null;
     }
 
-    protected void doGet(final HttpServletRequest request, final HttpServletResponse response, final String format)
+    protected void doGet(final HttpServletRequest request, final HttpServletResponse response, String pathTokensStr, String format)
             throws ServletException, IOException {
         HealthCheckSelector selector = HealthCheckSelector.empty();
-        String pathInfo = request.getPathInfo();
-        String pathTokensStr = StringUtils.removeStart(splitFormat(pathInfo)[0], "/");
+
 
         List<String> tags = new ArrayList<String>();
         List<String> names = new ArrayList<String>();
@@ -255,7 +253,7 @@ public class HealthCheckExecutorServlet extends HttpServlet {
 
         if (names.size() == 0) {
             // if not provided via path use parameter or default
-            names = Arrays.asList(StringUtils.defaultIfEmpty(request.getParameter(PARAM_NAMES.name), "").split(PARAM_SPLIT_REGEX));
+            names = Arrays.asList(StringUtils.defaultIfBlank(request.getParameter(PARAM_NAMES.name), "").split(PARAM_SPLIT_REGEX));
         }
         selector.withNames(names.toArray(new String[0]));
 
@@ -272,7 +270,7 @@ public class HealthCheckExecutorServlet extends HttpServlet {
         executionOptions.setForceInstantExecution(Boolean.valueOf(request.getParameter(PARAM_FORCE_INSTANT_EXECUTION.name)));
         
         String overrideGlobalTimeoutVal = request.getParameter(PARAM_OVERRIDE_GLOBAL_TIMEOUT.name);
-        if (StringUtils.isNumeric(overrideGlobalTimeoutVal)) {
+        if (StringUtils.isNotBlank(overrideGlobalTimeoutVal)) {
             executionOptions.setOverrideGlobalTimeout(Integer.valueOf(overrideGlobalTimeoutVal));
         } else if(servletDefaultTimeout > -1) {
             executionOptions.setOverrideGlobalTimeout((int) servletDefaultTimeout);
@@ -295,10 +293,10 @@ public class HealthCheckExecutorServlet extends HttpServlet {
         } else if (FORMAT_JSON.equals(format)) {
             sendJsonResponse(overallResult, executionResults, null, response, includeDebug);
         } else if (FORMAT_JSONP.equals(format)) {
-            String jsonpCallback = StringUtils.defaultIfEmpty(request.getParameter(PARAM_JSONP_CALLBACK.name), JSONP_CALLBACK_DEFAULT);
+            String jsonpCallback = StringUtils.defaultIfBlank(request.getParameter(PARAM_JSONP_CALLBACK.name), JSONP_CALLBACK_DEFAULT);
             sendJsonResponse(overallResult, executionResults, jsonpCallback, response, includeDebug);
-        } else if (StringUtils.endsWith(format, FORMAT_TXT)) {
-            sendTxtResponse(overallResult, response, StringUtils.equals(format, FORMAT_VERBOSE_TXT), executionResults, includeDebug);
+        } else if (format != null && format.endsWith(FORMAT_TXT)) {
+            sendTxtResponse(overallResult, response, FORMAT_VERBOSE_TXT.equals(format), executionResults, includeDebug);
         } else {
             response.setContentType("text/plain");
             response.getWriter().println("Invalid format " + format + " - supported formats: html|json|jsonp|txt|verbose.txt");
@@ -308,19 +306,26 @@ public class HealthCheckExecutorServlet extends HttpServlet {
     @Override
     protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
         String pathInfo = request.getPathInfo();
-        String format = splitFormat(pathInfo)[1];
+        String[] splitPathInfo = splitFormat(pathInfo);
+        String format = splitPathInfo[1];
         if (StringUtils.isBlank(format)) {
             // if not provided via extension use parameter or default
-            format = StringUtils.defaultIfEmpty(request.getParameter(PARAM_FORMAT.name), defaultFormat);
+            format = StringUtils.defaultIfBlank(request.getParameter(PARAM_FORMAT.name), defaultFormat);
+        }
+        
+        String pathTokensStr = splitPathInfo[0];
+        if(pathTokensStr!=null && pathTokensStr.startsWith("/")) {
+            pathTokensStr = pathTokensStr.substring(1, pathTokensStr.length());
         }
-        doGet(request, response, format);
+
+        doGet(request, response, pathTokensStr, format);
     }
 
-    private String[] splitFormat(String pathInfo) {
+    String[] splitFormat(String pathInfo) {
         for (String format : new String[] { FORMAT_HTML, FORMAT_JSON, FORMAT_JSONP, FORMAT_VERBOSE_TXT, FORMAT_TXT }) {
             String formatWithDot = "." + format;
-            if (StringUtils.endsWith(pathInfo, formatWithDot)) {
-                return new String[] { StringUtils.substringBeforeLast(pathInfo, formatWithDot), format };
+            if (pathInfo != null && pathInfo.endsWith(formatWithDot)) {
+                return new String[] { pathInfo.substring(0, pathInfo.length() - formatWithDot.length()), format };
             }
         }
         return new String[] { pathInfo, null };
@@ -358,7 +363,7 @@ public class HealthCheckExecutorServlet extends HttpServlet {
             throws IOException {
         response.setContentType(CONTENT_TYPE_HTML);
         response.setCharacterEncoding("UTF-8");
-        response.getWriter().append(this.htmlSerializer.serialize(overallResult, executionResults, getHtmlHelpText(), includeDebug));
+        response.getWriter().append(this.htmlSerializer.serialize(overallResult, executionResults, Arrays.asList(PARAM_LIST), includeDebug));
     }
 
     private void sendNoCacheHeaders(final HttpServletResponse response) {
@@ -371,17 +376,6 @@ public class HealthCheckExecutorServlet extends HttpServlet {
         }
     }
 
-    private String getHtmlHelpText() {
-        final StringBuilder sb = new StringBuilder();
-        sb.append("<h3>Supported URL parameters</h3>\n");
-        for (Param p : PARAM_LIST) {
-            sb.append("<b>").append(p.name).append("</b>:");
-            sb.append(StringEscapeUtils.escapeHtml4(p.description));
-            sb.append("<br/>");
-        }
-        return sb.toString();
-    }
-
     Map<Result.Status, Integer> getStatusMapping(String mappingStr) {
         Map<Result.Status, Integer> statusMapping = new TreeMap<Result.Status, Integer>();
         
@@ -424,7 +418,7 @@ public class HealthCheckExecutorServlet extends HttpServlet {
 
         @Override
         protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-            HealthCheckExecutorServlet.this.doGet(req, resp, format);
+            HealthCheckExecutorServlet.this.doGet(req, resp, "", format);
         }
     }
 
diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultHtmlSerializer.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultHtmlSerializer.java
index c315c8b..8b0477c 100644
--- a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultHtmlSerializer.java
+++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultHtmlSerializer.java
@@ -27,11 +27,11 @@ import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
 
-import org.apache.commons.lang3.StringEscapeUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.hc.api.Result;
 import org.apache.felix.hc.api.ResultLog.Entry;
 import org.apache.felix.hc.api.execution.HealthCheckExecutionResult;
+import org.apache.felix.hc.core.impl.servlet.HealthCheckExecutorServlet.Param;
+import org.apache.felix.hc.core.impl.util.lang.StringUtils;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 
@@ -46,7 +46,7 @@ public class ResultHtmlSerializer {
         this.styleString = configuration.styleString();
     }
 
-    public String serialize(final Result overallResult, final List<HealthCheckExecutionResult> executionResults, String escapedHelpText,
+    public String serialize(final Result overallResult, final List<HealthCheckExecutionResult> executionResults, List<Param> paramList,
             boolean includeDebug) {
 
         StringWriter stringWriter = new StringWriter();
@@ -70,13 +70,13 @@ public class ResultHtmlSerializer {
             List<String> tags = executionResult.getHealthCheckMetadata().getTags();
             boolean hasTags = tags != null && tags.size() > 0 && StringUtils.isNotBlank(tags.get(0));
             writer.print("<tr class=\"" + getClassForStatus(result.getStatus()) + "\">");
-            writer.print("<td><p title=\"" + StringEscapeUtils.escapeHtml4(executionResult.getHealthCheckMetadata().getName()) + "\">"
-                    + StringEscapeUtils.escapeHtml4(executionResult.getHealthCheckMetadata().getTitle()) + "");
+            writer.print("<td><p title=\"" + escapeHtml(executionResult.getHealthCheckMetadata().getName()) + "\">"
+                    + escapeHtml(executionResult.getHealthCheckMetadata().getTitle()) + "");
             if (hasTags) {
-                writer.println("<br/><span style='color:gray'>" + StringEscapeUtils.escapeHtml4(StringUtils.join(tags, ", ")) + "</span>");
+                writer.println("<br/><span style='color:gray'>" + escapeHtml(String.join(", ", tags)) + "</span>");
             }
             writer.println("</p></td>");
-            writer.println("<td style='font-weight:bold;'>" + StringEscapeUtils.escapeHtml4(result.getStatus().toString()) + "</td>");
+            writer.println("<td style='font-weight:bold;'>" + escapeHtml(result.getStatus().toString()) + "</td>");
             writer.println("<td>");
             boolean isFirst = true;
 
@@ -95,15 +95,15 @@ public class ResultHtmlSerializer {
 
                 boolean showStatus = !isSingleResult && !entry.isDebug() && entry.getStatus() != Result.Status.OK;
 
-                String message = StringEscapeUtils.escapeHtml4(entry.getMessage());
+                String message = escapeHtml(entry.getMessage());
                 if (entry.isDebug()) {
                     message = "<span style='color:gray'/>" + message + "</span>";
                 }
-                writer.println((showStatus ? StringEscapeUtils.escapeHtml4(entry.getStatus().toString()) + " " : "") + message);
+                writer.println((showStatus ? escapeHtml(entry.getStatus().toString()) + " " : "") + message);
 
                 Exception exception = entry.getException();
                 if (exception != null) {
-                    writer.println("<span style='width:20px'/>" + StringEscapeUtils.escapeHtml4(exception.toString()));
+                    writer.println("<span style='width:20px'/>" + escapeHtml(exception.toString()));
                     writer.println("<!--");
                     exception.printStackTrace(writer);
                     writer.println("-->");
@@ -119,7 +119,7 @@ public class ResultHtmlSerializer {
         writer.println("</table>");
 
         writer.println("<div class='helpText'>");
-        writer.println(escapedHelpText);
+        writer.println(getHtmlHelpText(paramList));
         writer.println("</div>");
         writer.println("</body></html>");
 
@@ -151,4 +151,23 @@ public class ResultHtmlSerializer {
         return isToday;
 
     }
+    
+    private String getHtmlHelpText(List<Param> paramList) {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("<h3>Supported URL parameters</h3>\n");
+        for (Param p : paramList) {
+            sb.append("<b>").append(p.name).append("</b>:");
+            sb.append(escapeHtml(p.description));
+            sb.append("<br/>");
+        }
+        return sb.toString();
+    }
+
+    private String escapeHtml(String text) {
+        return text
+                .replace("&", "&amp;")
+                .replace("\"", "&quot;")
+                .replace("<", "&lt;")
+                .replace(">", "&gt;");
+    }
 }
diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultJsonSerializer.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultJsonSerializer.java
index c373d66..61eefe9 100644
--- a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultJsonSerializer.java
+++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultJsonSerializer.java
@@ -23,10 +23,10 @@ import java.io.StringWriter;
 import java.text.SimpleDateFormat;
 import java.util.List;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.hc.api.Result;
 import org.apache.felix.hc.api.ResultLog;
 import org.apache.felix.hc.api.execution.HealthCheckExecutionResult;
+import org.apache.felix.hc.core.impl.util.lang.StringUtils;
 import org.apache.felix.utils.json.JSONWriter;
 import org.osgi.service.component.annotations.Component;
 import org.slf4j.Logger;
diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultTxtVerboseSerializer.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultTxtVerboseSerializer.java
index 9d20a4b..8192636 100644
--- a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultTxtVerboseSerializer.java
+++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultTxtVerboseSerializer.java
@@ -23,11 +23,10 @@ import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.List;
 
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.text.WordUtils;
 import org.apache.felix.hc.api.Result;
 import org.apache.felix.hc.api.ResultLog;
 import org.apache.felix.hc.api.execution.HealthCheckExecutionResult;
+import org.apache.felix.hc.core.impl.util.lang.StringUtils;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.slf4j.Logger;
@@ -70,11 +69,11 @@ public class ResultTxtVerboseSerializer {
         StringBuilder resultStr = new StringBuilder();
 
         resultStr.append(StringUtils.repeat("-", totalWidth) + NEWLINE);
-        resultStr.append(StringUtils.center("Overall Health Result: " + overallResult.getStatus().toString(), totalWidth) + NEWLINE);
+        resultStr.append(center("Overall Health Result: " + overallResult.getStatus().toString(), totalWidth) + NEWLINE);
         resultStr.append(StringUtils.repeat("-", totalWidth) + NEWLINE);
-        resultStr.append(StringUtils.rightPad("Name", colWidthName));
-        resultStr.append(StringUtils.rightPad("Result", colWidthResult));
-        resultStr.append(StringUtils.rightPad("Timing", colWidthTiming));
+        resultStr.append(rightPad("Name", colWidthName));
+        resultStr.append(rightPad("Result", colWidthResult));
+        resultStr.append(rightPad("Timing", colWidthTiming));
         resultStr.append("Logs" + NEWLINE);
         resultStr.append(StringUtils.repeat("-", totalWidth) + NEWLINE);
 
@@ -92,15 +91,15 @@ public class ResultTxtVerboseSerializer {
     private void appendVerboseTxtForResult(StringBuilder resultStr, HealthCheckExecutionResult healthCheckResult, boolean includeDebug,
             DateFormat dfShort) {
 
-        String wrappedName = WordUtils.wrap(healthCheckResult.getHealthCheckMetadata().getTitle(), colWidthName);
+        String wrappedName = wordWrap(healthCheckResult.getHealthCheckMetadata().getTitle(), colWidthName, "\n");
 
-        String relevantNameStringForPadding = StringUtils.contains(wrappedName, "\n") ? StringUtils.substringAfterLast(wrappedName, "\n")
-                : wrappedName;
+        int lastIndexOfNewline = wrappedName.lastIndexOf("\n");
+        String relevantNameStringForPadding = lastIndexOfNewline >= 0 ? wrappedName.substring(lastIndexOfNewline+1) : wrappedName;
         int paddingSize = colWidthName - relevantNameStringForPadding.length();
 
         resultStr.append(wrappedName + StringUtils.repeat(" ", paddingSize));
-        resultStr.append(StringUtils.rightPad(healthCheckResult.getHealthCheckResult().getStatus().toString(), colWidthResult));
-        resultStr.append(StringUtils.rightPad("[" + dfShort.format(healthCheckResult.getFinishedAt())
+        resultStr.append(rightPad(healthCheckResult.getHealthCheckResult().getStatus().toString(), colWidthResult));
+        resultStr.append(rightPad("[" + dfShort.format(healthCheckResult.getFinishedAt())
                 + "|" + msHumanReadable(healthCheckResult.getElapsedTimeInMs()) + "]", colWidthTiming));
 
         boolean isFirst = true;
@@ -115,7 +114,7 @@ public class ResultTxtVerboseSerializer {
             }
 
             String oneLineMessage = getStatusForTxtLog(logEntry) + logEntry.getMessage();
-            String messageToPrint = WordUtils.wrap(oneLineMessage, colWidthLog, "\n" + StringUtils.repeat(" ", colWidthWithoutLog), true);
+            String messageToPrint = wordWrap(oneLineMessage, colWidthLog, "\n" + StringUtils.repeat(" ", colWidthWithoutLog));
 
             resultStr.append(messageToPrint);
             resultStr.append(NEWLINE);
@@ -136,4 +135,31 @@ public class ResultTxtVerboseSerializer {
         }
     }
 
+    // -- Some simple helpers directly here as commons lang is removed
+
+    String wordWrap(String s, int maxWidth, String newlineDelimiter) {
+        return s.replaceAll("(.{1,"+maxWidth+"})(?: +|$)\\n?|(.{"+maxWidth+"})", "$1$2"+newlineDelimiter).trim();
+    }
+    
+    static String rightPad(String s, int size) {
+        if(s.length() < size) {
+            return s + StringUtils.repeat(" ", size - s.length());
+        } else {
+            return s;
+        }
+    }
+    
+    static String center(String s, int size) {
+        if(s.length() < size) {
+            int padding = size - s.length();
+            int paddingLeft = padding / 2;
+            int paddingRight = padding / 2;
+            if(padding % 2 == 1) {
+                paddingRight++;
+            }
+            return StringUtils.repeat(" ", paddingLeft) + s + StringUtils.repeat(" ", paddingRight);
+        } else {
+            return s;
+        }
+    }
 }
diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/util/lang/StringUtils.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/util/lang/StringUtils.java
new file mode 100644
index 0000000..2cb0e46
--- /dev/null
+++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/util/lang/StringUtils.java
@@ -0,0 +1,52 @@
+/*
+ * 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 SF 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.felix.hc.core.impl.util.lang;
+
+/** Simple class for commons lang replacement where Java 8 does not provide replacements.
+ *  
+ *  Java 11 will allow to use String.isBlank() and String.repeat(), then this class can 
+ *  be removed. 
+ *  
+ *  HINT: This class is also used in generalchecks via Conditional-Package */
+public class StringUtils {
+
+    public static boolean isBlank(final CharSequence cs) {
+        return cs == null || cs.chars().allMatch(Character::isWhitespace);
+    }
+
+    public static boolean isNotBlank(final CharSequence cs) {
+        return !isBlank(cs);
+    }
+
+    public static String defaultIfBlank(final String cs, String defaultStr) {
+        return isBlank(cs) ? defaultStr : cs;
+    }
+    
+    public static String repeat(String s, int n) {
+        if(s == null) {
+            return null;
+        }
+        final StringBuilder sb = new StringBuilder(s.length() * n);
+        for(int i = 0; i < n; i++) {
+            sb.append(s);
+        }
+        return sb.toString();
+    }
+
+
+}
diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/jmx/impl/HealthCheckMBeanCreator.java b/healthcheck/core/src/main/java/org/apache/felix/hc/jmx/impl/HealthCheckMBeanCreator.java
index 248971b..38c3b25 100644
--- a/healthcheck/core/src/main/java/org/apache/felix/hc/jmx/impl/HealthCheckMBeanCreator.java
+++ b/healthcheck/core/src/main/java/org/apache/felix/hc/jmx/impl/HealthCheckMBeanCreator.java
@@ -27,10 +27,10 @@ import java.util.Map;
 
 import javax.management.DynamicMBean;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.hc.api.HealthCheck;
 import org.apache.felix.hc.core.impl.executor.ExtendedHealthCheckExecutor;
 import org.apache.felix.hc.core.impl.util.HealthCheckFilter;
+import org.apache.felix.hc.core.impl.util.lang.StringUtils;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Filter;
 import org.osgi.framework.InvalidSyntaxException;
diff --git a/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServletTest.java b/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServletTest.java
index 979dae9..0a320ff 100644
--- a/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServletTest.java
+++ b/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServletTest.java
@@ -19,9 +19,7 @@ package org.apache.felix.hc.core.impl.servlet;
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.ArgumentMatchers.contains;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.never;
@@ -122,7 +120,7 @@ public class HealthCheckExecutorServletTest {
         verifyNoInteractions(verboseTxtSerializer);
         verify(htmlSerializer)
                 .serialize(resultEquals(new Result(Result.Status.CRITICAL, "Overall Status CRITICAL")), eq(executionResults),
-                        contains("Supported URL parameters"), eq(false));
+                        any(List.class), eq(false));
     }
 
     @Test
@@ -146,7 +144,7 @@ public class HealthCheckExecutorServletTest {
         verifyNoInteractions(verboseTxtSerializer);
         verify(htmlSerializer)
                 .serialize(resultEquals(new Result(Result.Status.CRITICAL, "Overall Status CRITICAL")), eq(executionResults),
-                        contains("Supported URL parameters"), eq(false));
+                        any(List.class), eq(false));
     }
 
     @Test
diff --git a/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/servlet/ResultTxtVerboseSerializerTest.java b/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/servlet/ResultTxtVerboseSerializerTest.java
new file mode 100644
index 0000000..9b27418
--- /dev/null
+++ b/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/servlet/ResultTxtVerboseSerializerTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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 SF 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.felix.hc.core.impl.servlet;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class ResultTxtVerboseSerializerTest {
+
+    ResultTxtVerboseSerializer resultTxtVerboseSerializer = new ResultTxtVerboseSerializer();
+    @Test
+    public void testWordWrap() {
+        String exampleText = "word1 word2 word3 word4 word5 word6 word7 word8 word9 word10";
+
+        assertEquals("word1 word2 word3\nword4 word5 word6\nword7 word8 word9\nword10", resultTxtVerboseSerializer.wordWrap(exampleText, 20, "\n"));
+        assertEquals("word1 word2 word3 word4 word5 word6\nword7 word8 word9 word10", resultTxtVerboseSerializer.wordWrap(exampleText, 40, "\n"));
+        
+        String longText = "Disk Usage /very/long/path/to/some/location/on/disk/somewhere/.: 88.6% of 465.6GB used / 53.1GB free";
+        assertEquals("Disk Usage\n/very/long/path/to/some/locati\non/on/disk/somewhere/.: 88.6%\nof 465.6GB used / 53.1GB free", resultTxtVerboseSerializer.wordWrap(longText, 30, "\n"));
+        
+    }
+
+}
diff --git a/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/util/StringUtilsTest.java b/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/util/StringUtilsTest.java
new file mode 100644
index 0000000..2cc88a8
--- /dev/null
+++ b/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/util/StringUtilsTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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 SF 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.felix.hc.core.impl.util;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.felix.hc.core.impl.util.lang.StringUtils;
+import org.junit.Test;
+
+public class StringUtilsTest {
+
+    @Test
+    public void testIsNotBlank() {
+        assertTrue(StringUtils.isNotBlank("test"));
+        assertTrue(StringUtils.isNotBlank("$"));
+        assertTrue(StringUtils.isNotBlank("123"));
+        assertFalse(StringUtils.isNotBlank("    "));
+        assertFalse(StringUtils.isNotBlank("\t"));
+    }
+    
+    @Test
+    public void testIsBlank() {
+        assertFalse(StringUtils.isBlank("test"));
+        assertFalse(StringUtils.isBlank("$"));
+        assertFalse(StringUtils.isBlank("123"));
+        assertTrue(StringUtils.isBlank("    "));
+        assertTrue(StringUtils.isBlank("\t"));
+    }
+
+}
diff --git a/healthcheck/core/src/test/java/org/apache/felix/hc/core/it/U.java b/healthcheck/core/src/test/java/org/apache/felix/hc/core/it/U.java
index d9efb83..c42b6c1 100644
--- a/healthcheck/core/src/test/java/org/apache/felix/hc/core/it/U.java
+++ b/healthcheck/core/src/test/java/org/apache/felix/hc/core/it/U.java
@@ -82,7 +82,6 @@ public class U {
                         mavenBundle("org.apache.felix", "org.apache.felix.eventadmin", "1.4.10"),
 
                         mavenBundle("org.apache.felix", "org.apache.felix.healthcheck.api").versionAsInProject(),
-                        mavenBundle().groupId("org.apache.commons").artifactId("commons-lang3").versionAsInProject(),
 
                         mavenBundle("org.apache.felix", "org.apache.felix.http.servlet-api", "1.1.2"),
                         mavenBundle("org.apache.felix", "org.apache.felix.http.jetty", "4.0.2"),
diff --git a/healthcheck/generalchecks/bnd.bnd b/healthcheck/generalchecks/bnd.bnd
index e37e4b6..e42dd06 100644
--- a/healthcheck/generalchecks/bnd.bnd
+++ b/healthcheck/generalchecks/bnd.bnd
@@ -8,7 +8,7 @@ Bundle-License: Apache License, Version 2.0
 
 Bundle-Vendor: The Apache Software Foundation
 
-Conditional-Package: org.apache.commons.cli.*,org.apache.felix.utils.*
+Conditional-Package: org.apache.commons.cli.*,org.apache.felix.utils.*,org.apache.felix.hc.core.impl.util.lang.*
 
 Export-Package: org.apache.felix.hc.generalchecks.util
 
diff --git a/healthcheck/generalchecks/pom.xml b/healthcheck/generalchecks/pom.xml
index e7873f8..00c873e 100644
--- a/healthcheck/generalchecks/pom.xml
+++ b/healthcheck/generalchecks/pom.xml
@@ -167,13 +167,6 @@
             <scope>provided</scope>
         </dependency>
 
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-lang3</artifactId>
-            <version>3.4</version>
-            <scope>provided</scope>
-        </dependency>
-        
         <!--  START provided via ConditionalPackage -->
         <dependency>
             <groupId>commons-cli</groupId>
@@ -187,6 +180,13 @@
             <version>1.11.0</version>
             <scope>provided</scope>
         </dependency>
+        <!-- only to be able to use org.apache.felix.hc.core.impl.util.StringUtils for commons lang replacement -->
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.healthcheck.core</artifactId>
+            <version>2.0.7-SNAPSHOT</version>
+            <scope>provided</scope>
+        </dependency>
         <!--  END provided via ConditionalPackage -->
 
         <!-- START test scope dependencies -->
diff --git a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/BundlesStartedCheck.java b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/BundlesStartedCheck.java
index 1065852..60d6788 100644
--- a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/BundlesStartedCheck.java
+++ b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/BundlesStartedCheck.java
@@ -19,11 +19,11 @@ package org.apache.felix.hc.generalchecks;
 
 import java.util.regex.Pattern;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.hc.annotation.HealthCheckService;
 import org.apache.felix.hc.api.FormattingResultLog;
 import org.apache.felix.hc.api.HealthCheck;
 import org.apache.felix.hc.api.Result;
+import org.apache.felix.hc.core.impl.util.lang.StringUtils;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
diff --git a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/DsComponentsCheck.java b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/DsComponentsCheck.java
index 3785b33..9fcbbd2 100644
--- a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/DsComponentsCheck.java
+++ b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/DsComponentsCheck.java
@@ -24,19 +24,18 @@ import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.hc.annotation.HealthCheckService;
 import org.apache.felix.hc.api.FormattingResultLog;
 import org.apache.felix.hc.api.HealthCheck;
 import org.apache.felix.hc.api.Result;
 import org.apache.felix.hc.api.ResultLog.Entry;
+import org.apache.felix.hc.core.impl.util.lang.StringUtils;
 import org.apache.felix.hc.generalchecks.scrutil.DsRootCauseAnalyzer;
 import org.osgi.framework.BundleContext;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.ConfigurationPolicy;
 import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.component.annotations.ReferenceCardinality;
 import org.osgi.service.component.annotations.ReferencePolicyOption;
 import org.osgi.service.component.runtime.ServiceComponentRuntime;
 import org.osgi.service.component.runtime.dto.ComponentConfigurationDTO;
@@ -128,7 +127,7 @@ public class DsComponentsCheck implements HealthCheck {
                         foundActiveOrSatisfiedConfig = true;
                     }
                 }
-                log.debug(dsComp.name + " (" + StringUtils.join(idStateTuples, ",") + ")");
+                log.debug(dsComp.name + " (" + String.join(",", idStateTuples) + ")");
 
                 if (componentConfigurationDTOs.isEmpty() || foundActiveOrSatisfiedConfig) {
                     countEnabled++;
diff --git a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/FrameworkStartCheck.java b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/FrameworkStartCheck.java
index 4618fd7..6f21eeb 100644
--- a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/FrameworkStartCheck.java
+++ b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/FrameworkStartCheck.java
@@ -18,10 +18,10 @@
  */
 package org.apache.felix.hc.generalchecks;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.hc.annotation.HealthCheckService;
 import org.apache.felix.hc.api.HealthCheck;
 import org.apache.felix.hc.api.Result;
+import org.apache.felix.hc.core.impl.util.lang.StringUtils;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
diff --git a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/HttpRequestsCheck.java b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/HttpRequestsCheck.java
index 2dc682e..9729f56 100644
--- a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/HttpRequestsCheck.java
+++ b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/HttpRequestsCheck.java
@@ -33,6 +33,7 @@ import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Base64;
 import java.util.HashMap;
 import java.util.List;
@@ -48,12 +49,12 @@ import org.apache.commons.cli.CommandLineParser;
 import org.apache.commons.cli.DefaultParser;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.hc.annotation.HealthCheckService;
 import org.apache.felix.hc.api.FormattingResultLog;
 import org.apache.felix.hc.api.HealthCheck;
 import org.apache.felix.hc.api.Result;
 import org.apache.felix.hc.api.ResultLog;
+import org.apache.felix.hc.core.impl.util.lang.StringUtils;
 import org.apache.felix.hc.generalchecks.util.SimpleConstraintChecker;
 import org.apache.felix.utils.json.JSONParser;
 import org.osgi.framework.BundleContext;
@@ -234,15 +235,15 @@ public class HttpRequestsCheck implements HealthCheck {
             
             String[] responseAssertionArr = responseAssertions.split(" +&& +");
             for(String clause: responseAssertionArr) {
-                if(StringUtils.isNumeric(clause)) {
+                if(isNumeric(clause)) {
                     responseChecks.add(new ResponseCodeCheck(Integer.parseInt(clause)));
-                } else if(StringUtils.startsWithIgnoreCase(clause, ResponseTimeCheck.TIME)) {
+                } else if(clause.toUpperCase().startsWith(ResponseTimeCheck.TIME)) {
                     responseChecks.add(new ResponseTimeCheck(clause.substring(ResponseTimeCheck.TIME.length())));
-                } else if(StringUtils.startsWithIgnoreCase(clause, ResponseEntityRegExCheck.MATCHES)) {
+                } else if(clause.toUpperCase().startsWith(ResponseEntityRegExCheck.MATCHES)) {
                     responseChecks.add(new ResponseEntityRegExCheck(Pattern.compile(clause.substring(ResponseEntityRegExCheck.MATCHES.length()))));
-                } else if(StringUtils.startsWithIgnoreCase(clause, ResponseHeaderCheck.HEADER)) {
+                } else if(clause.toUpperCase().startsWith(ResponseHeaderCheck.HEADER)) {
                     responseChecks.add(new ResponseHeaderCheck(clause.substring(ResponseHeaderCheck.HEADER.length())));
-                } else if(StringUtils.startsWithIgnoreCase(clause, JsonPropertyCheck.JSON)) {
+                } else if(clause.toUpperCase().startsWith(JsonPropertyCheck.JSON)) {
                     responseChecks.add(new JsonPropertyCheck(clause.substring(JsonPropertyCheck.JSON.length())));
                 } else {
                     throw new IllegalArgumentException("Invalid response content assertion clause: '"+clause+"'");
@@ -250,6 +251,15 @@ public class HttpRequestsCheck implements HealthCheck {
             }
         }
 
+        private boolean isNumeric(String text) {
+            try {
+                Integer.parseInt(text);
+                return true;
+            } catch(NumberFormatException e) {
+                return false;
+            }
+        }
+
         private void parseCurlLikeRequestInfo(String requestInfo) throws ParseException, URISyntaxException {
             CommandLineParser parser = new DefaultParser();
 
@@ -356,7 +366,7 @@ public class HttpRequestsCheck implements HealthCheck {
                 Result.Status status = hasFailed ? statusForFailedContraint : Result.Status.OK;
                 String timing = showTiming ? " " + msHumanReadable(response.requestDurationInMs) : "";
                 // result of response assertion(s)
-                log.add(new ResultLog.Entry(status, urlWithUser+timing+": "+ StringUtils.join(resultBits,", ")));
+                log.add(new ResultLog.Entry(status, urlWithUser+timing+": "+ String.join(", ", resultBits)));
             }
 
             return log;
@@ -601,13 +611,14 @@ public class HttpRequestsCheck implements HealthCheck {
             Object currentObject = null;
             for (int i=0; i < jsonPropertyPathBits.length; i++) {
                 String jsonPropertyPathBit = jsonPropertyPathBits[i];
+                String propPathForEx = StringUtils.defaultIfBlank(String.join("", Arrays.copyOfRange(jsonPropertyPathBits, 0, i)), "<root>");
                 if(jsonPropertyPathBit.startsWith("[")) {
                     int arrayIndex = Integer.parseInt(jsonPropertyPathBit.substring(1,jsonPropertyPathBit.length()-1));
                     if(currentObject==null) {
                         currentObject = jsonParser.getParsedList();
                     }
                     if(!(currentObject instanceof List)) {
-                        throw new IllegalArgumentException("Path '"+StringUtils.defaultIfEmpty(StringUtils.join(jsonPropertyPathBits, "", 0, i), "<root>")+"' is not a json list");
+                        throw new IllegalArgumentException("Path '"+propPathForEx+"' is not a json list");
                     }
                     currentObject = ((List<?>) currentObject).get(arrayIndex);
                 } else {
@@ -616,12 +627,13 @@ public class HttpRequestsCheck implements HealthCheck {
                         currentObject = jsonParser.getParsed();
                     }
                     if(!(currentObject instanceof Map)) {
-                        throw new IllegalArgumentException("Path '"+StringUtils.defaultIfEmpty(StringUtils.join(jsonPropertyPathBits, "", 0, i), "<root>")+"' is not a json object");
+                        throw new IllegalArgumentException("Path '"+propPathForEx+"' is not a json object");
                     }
                     currentObject = ((Map<?,?>) currentObject).get(propertyName);
                 }
                 if(currentObject==null && /* not last */ i+1 < jsonPropertyPathBits.length) {
-                    throw new IllegalArgumentException("Path "+StringUtils.join(jsonPropertyPathBits, "", 0, i+1)+" is null, cannot evaluate left-over part '"+StringUtils.join(jsonPropertyPathBits, "", i+1, jsonPropertyPathBits.length)+"'");
+                    String unevaluated = String.join("", Arrays.copyOfRange(jsonPropertyPathBits, i+1, jsonPropertyPathBits.length));
+                    throw new IllegalArgumentException("Path "+propPathForEx+" is null, cannot evaluate left-over part '"+unevaluated+"'");
                 }
             }
             return currentObject;
diff --git a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/JmxAttributeCheck.java b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/JmxAttributeCheck.java
index 9fdf0bb..ba545bc 100644
--- a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/JmxAttributeCheck.java
+++ b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/JmxAttributeCheck.java
@@ -25,11 +25,11 @@ import java.util.Map;
 import javax.management.MBeanServer;
 import javax.management.ObjectName;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.hc.api.FormattingResultLog;
 import org.apache.felix.hc.api.HealthCheck;
 import org.apache.felix.hc.api.Result;
 import org.apache.felix.hc.api.ResultLog;
+import org.apache.felix.hc.core.impl.util.lang.StringUtils;
 import org.apache.felix.hc.generalchecks.util.SimpleConstraintChecker;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
@@ -176,7 +176,7 @@ public class JmxAttributeCheck implements HealthCheck {
             this.mbeanName = StringUtils.defaultIfBlank(mBeanName, defaultMBeanName);
             this.attributeName = (String) rawConfig.get(propNameAttribute);
             this.attributeValueConstraint = (String) rawConfig.get(PROP_ATTRIBUTE + attributeCounter + SUFFIX_VALUE_CONSTRAINT);
-            if(StringUtils.isAnyBlank(mbeanName, attributeName, attributeValueConstraint)) {
+            if(StringUtils.isBlank(mbeanName) || StringUtils.isBlank(attributeName) || StringUtils.isBlank(attributeValueConstraint)) {
                 throw new IllegalArgumentException("Invalid JmxAttributeCheck config for property "+mbeanName+" -> "+propNameAttribute+": "+toString());
             }
         }
diff --git a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/ScriptedHealthCheck.java b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/ScriptedHealthCheck.java
index bb83f1e..49a7bb6 100644
--- a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/ScriptedHealthCheck.java
+++ b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/ScriptedHealthCheck.java
@@ -19,10 +19,10 @@ package org.apache.felix.hc.generalchecks;
 
 import javax.script.ScriptEngine;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.hc.api.FormattingResultLog;
 import org.apache.felix.hc.api.HealthCheck;
 import org.apache.felix.hc.api.Result;
+import org.apache.felix.hc.core.impl.util.lang.StringUtils;
 import org.apache.felix.hc.generalchecks.util.ScriptEnginesTracker;
 import org.apache.felix.hc.generalchecks.util.ScriptHelper;
 import org.osgi.framework.BundleContext;
diff --git a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/ScriptHelper.java b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/ScriptHelper.java
index c6b8e7d..fc93558 100644
--- a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/ScriptHelper.java
+++ b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/ScriptHelper.java
@@ -39,10 +39,10 @@ import javax.script.ScriptException;
 import javax.script.SimpleBindings;
 import javax.script.SimpleScriptContext;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.hc.api.FormattingResultLog;
 import org.apache.felix.hc.api.Result;
 import org.apache.felix.hc.api.ResultLog;
+import org.apache.felix.hc.core.impl.util.lang.StringUtils;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
diff --git a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/SimpleConstraintChecker.java b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/SimpleConstraintChecker.java
index 96eaa30..c531a89 100644
--- a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/SimpleConstraintChecker.java
+++ b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/SimpleConstraintChecker.java
@@ -17,9 +17,10 @@
  */
 package org.apache.felix.hc.generalchecks.util;
 
+import java.util.Arrays;
 import java.util.Calendar;
 
-import org.apache.commons.lang3.StringUtils;
+import org.apache.felix.hc.core.impl.util.lang.StringUtils;
 
 /** Simple check of values against expressions like &lt; N, &gt; N, between two values etc. See the SimpleConstraintCheckerTest for
  * examples. */
@@ -73,9 +74,9 @@ public class SimpleConstraintChecker {
             matches = value < Long.valueOf(parts[1]);
 
         } else if (parts[0].equals(EQUALS) && parts.length == 2) {
-            if(StringUtils.isNumeric(stringValue)) {
-                long value = Long.valueOf(stringValue).longValue();
-                matches = value == Long.valueOf(parts[1]).longValue();
+            Long longValue;
+            if((longValue = getLongObject(stringValue)) != null) {
+                matches = longValue.longValue() == Long.valueOf(parts[1]).longValue();
             } else {
                 matches = stringValue.equals(parts[1]);
             }
@@ -86,16 +87,16 @@ public class SimpleConstraintChecker {
             matches = value > lowerBound && value < upperBound;
 
         } else if (parts.length > 1 && CONTAINS.equalsIgnoreCase(parts[0])) {
-            String pattern = StringUtils.join(parts, " ", 1, parts.length);
+            String pattern = String.join(" ", Arrays.copyOfRange(parts, 1, parts.length));
             matches = stringValue.contains(pattern);
         } else if (parts.length > 1 && STARTS_WITH.equalsIgnoreCase(parts[0])) {
-            String pattern = StringUtils.join(parts, " ", 1, parts.length);
+            String pattern = String.join(" ", Arrays.copyOfRange(parts, 1, parts.length));
             matches = stringValue.startsWith(pattern);
         } else if (parts.length > 1 && ENDS_WITH.equalsIgnoreCase(parts[0])) {
-            String pattern = StringUtils.join(parts, " ", 1, parts.length);
+            String pattern = String.join(" ", Arrays.copyOfRange(parts, 1, parts.length));
             matches = stringValue.endsWith(pattern);
         } else if (parts.length > 1 && MATCHES.equalsIgnoreCase(parts[0])) {
-            String pattern = StringUtils.join(parts, " ", 1, parts.length);
+            String pattern = String.join(" ", Arrays.copyOfRange(parts, 1, parts.length));
             matches = stringValue.matches(pattern);
         } else if (parts.length > 1 && OLDER_THAN.equalsIgnoreCase(parts[0]) && parts.length == 3) {
             int unit = stringToUnit(parts[2]);
@@ -109,7 +110,7 @@ public class SimpleConstraintChecker {
             matches = timestamp < compareTimestamp;
 
         } else {
-            matches = StringUtils.join(parts, "").equals(stringValue);
+            matches = String.join("", parts).equals(stringValue);
         }
 
         boolean result = matches ^ inverseResult;
@@ -144,4 +145,15 @@ public class SimpleConstraintChecker {
         }
         return unit;
     }
+    
+    private static Long getLongObject(String strNum) {
+        if (strNum == null) {
+            return null;
+        }
+        try {
+            return Long.valueOf(strNum);
+        } catch (NumberFormatException nfe) {
+            return null;
+        }
+    }
 }
\ No newline at end of file
diff --git a/healthcheck/webconsoleplugin/pom.xml b/healthcheck/webconsoleplugin/pom.xml
index a2dff58..cb152bf 100644
--- a/healthcheck/webconsoleplugin/pom.xml
+++ b/healthcheck/webconsoleplugin/pom.xml
@@ -36,7 +36,10 @@
     <description>
         Plugin for the felix web console
     </description>
-
+    
+    <properties>
+        <felix.java.version>8</felix.java.version>
+    </properties>
     <scm>
         <connection>scm:git:https://github.com/apache/felix-dev.git</connection>
         <developerConnection>scm:git:https://github.com/apache/felix-dev.git</developerConnection>
@@ -103,14 +106,6 @@
             <version>1.7.6</version>
             <scope>provided</scope>
         </dependency>
-        
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-lang3</artifactId>
-            <version>3.4</version>
-            <scope>provided</scope>
-        </dependency>
-        
 
         <!-- START test scope dependencies -->
         <dependency>
diff --git a/healthcheck/webconsoleplugin/src/main/java/org/apache/felix/hc/webconsole/impl/HealthCheckWebconsolePlugin.java b/healthcheck/webconsoleplugin/src/main/java/org/apache/felix/hc/webconsole/impl/HealthCheckWebconsolePlugin.java
index a858a29..46ff61e 100644
--- a/healthcheck/webconsoleplugin/src/main/java/org/apache/felix/hc/webconsole/impl/HealthCheckWebconsolePlugin.java
+++ b/healthcheck/webconsoleplugin/src/main/java/org/apache/felix/hc/webconsole/impl/HealthCheckWebconsolePlugin.java
@@ -17,7 +17,6 @@
  */
 package org.apache.felix.hc.webconsole.impl;
 
-import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4;
 import static org.apache.felix.hc.api.FormattingResultLog.msHumanReadable;
 
 import java.io.IOException;
@@ -33,7 +32,6 @@ import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.hc.api.Result;
 import org.apache.felix.hc.api.ResultLog;
 import org.apache.felix.hc.api.execution.HealthCheckExecutionOptions;
@@ -126,7 +124,7 @@ public class HealthCheckWebconsolePlugin extends HttpServlet {
                 // override not set in UI
             }
 
-            HealthCheckSelector selector = StringUtils.isNotBlank(tags) ? HealthCheckSelector.tags(tags.split(",")) : HealthCheckSelector.empty();
+            HealthCheckSelector selector = !isBlank(tags) ? HealthCheckSelector.tags(tags.split(",")) : HealthCheckSelector.empty();
             Collection<HealthCheckExecutionResult> results = healthCheckExecutor.execute(selector, options);
 
             pw.println("<table class='content healthcheck' cellpadding='0' cellspacing='0' width='100%'>");
@@ -151,6 +149,10 @@ public class HealthCheckWebconsolePlugin extends HttpServlet {
 
         }
     }
+    
+    private static boolean isBlank(final CharSequence cs) {
+        return cs == null || cs.chars().allMatch(Character::isWhitespace);
+    }
 
     void renderResult(final PrintWriter pw, final HealthCheckExecutionResult exResult, final boolean debug)  throws IOException {
         final Result result = exResult.getHealthCheckResult();
@@ -166,7 +168,7 @@ public class HealthCheckWebconsolePlugin extends HttpServlet {
 
         c.tr();
         c.tdContent();
-        c.writer().print(escapeHtml4(status.toString()));
+        c.writer().print(c.escapeHtml(status.toString()));
         c.writer().print("<br/>Result: <span class='resultOk");
         c.writer().print(result.isOk());
         c.writer().print("'>");
@@ -186,10 +188,10 @@ public class HealthCheckWebconsolePlugin extends HttpServlet {
             c.writer().print("'>");
             c.writer().print(e.getStatus().toString());
             c.writer().print(' ');
-            c.writer().print(escapeHtml4(e.getMessage()));
+            c.writer().print(c.escapeHtml(e.getMessage()));
             if (e.getException() != null) {
                 c.writer().print(" ");
-                c.writer().print(escapeHtml4(e.getException().toString()));
+                c.writer().print(c.escapeHtml(e.getException().toString()));
             }
             c.writer().println("</div>");
         }
@@ -215,7 +217,7 @@ public class HealthCheckWebconsolePlugin extends HttpServlet {
         c.tdContent();
         c.writer().print("<input type='text' name='" + PARAM_TAGS + "' value='");
         if ( tags != null ) {
-            c.writer().print(escapeHtml4(tags));
+            c.writer().print(c.escapeHtml(tags));
         }
         c.writer().println("' class='input' size='80'>");
         c.closeTd();
@@ -270,7 +272,7 @@ public class HealthCheckWebconsolePlugin extends HttpServlet {
         c.tdContent();
         c.writer().print("<input type='text' name='" + PARAM_OVERRIDE_GLOBAL_TIMEOUT + "' value='");
         if (overrideGlobalTimeoutStr != null) {
-            c.writer().print(escapeHtml4(overrideGlobalTimeoutStr));
+            c.writer().print(c.escapeHtml(overrideGlobalTimeoutStr));
         }
         c.writer().println("' class='input' size='80'>");
         c.closeTd();
diff --git a/healthcheck/webconsoleplugin/src/main/java/org/apache/felix/hc/webconsole/impl/WebConsoleHelper.java b/healthcheck/webconsoleplugin/src/main/java/org/apache/felix/hc/webconsole/impl/WebConsoleHelper.java
index 6ffeeeb..f3257bc 100644
--- a/healthcheck/webconsoleplugin/src/main/java/org/apache/felix/hc/webconsole/impl/WebConsoleHelper.java
+++ b/healthcheck/webconsoleplugin/src/main/java/org/apache/felix/hc/webconsole/impl/WebConsoleHelper.java
@@ -19,8 +19,6 @@ package org.apache.felix.hc.webconsole.impl;
 
 import java.io.PrintWriter;
 
-import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4;
-
 /** Webconsole plugin helper for writing html. */
 class WebConsoleHelper {
 
@@ -48,7 +46,7 @@ class WebConsoleHelper {
 
     void tdLabel(final String label) {
         pw.print("<td class='content'>");
-        pw.print(escapeHtml4(label));
+        pw.print(escapeHtml(label));
         pw.println("</td>");
     }
 
@@ -59,16 +57,24 @@ class WebConsoleHelper {
     void titleHtml(String title, String description) {
         tr();
         pw.print("<th colspan='3' class='content container'>");
-        pw.print(escapeHtml4(title));
+        pw.print(escapeHtml(title));
         pw.println("</th>");
         closeTr();
 
         if (description != null) {
             tr();
             pw.print("<td colspan='3' class='content'>");
-            pw.print(escapeHtml4(description));
+            pw.print(escapeHtml(description));
             pw.println("</th>");
             closeTr();
         }
     }
+    
+    String escapeHtml(String text) {
+        return text
+                .replace("&", "&amp;")
+                .replace("\"", "&quot;")
+                .replace("<", "&lt;")
+                .replace(">", "&gt;");
+    }
 }