You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cz...@apache.org on 2023/08/16 06:13:18 UTC

[felix-dev] branch jakarta-servlet-6 updated: Port latest webconsole changes from main branch, use released artifacts, allow Java 11

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

cziegeler pushed a commit to branch jakarta-servlet-6
in repository https://gitbox.apache.org/repos/asf/felix-dev.git


The following commit(s) were added to refs/heads/jakarta-servlet-6 by this push:
     new 394e39c704 Port latest webconsole changes from main branch, use released artifacts, allow Java 11
394e39c704 is described below

commit 394e39c7049b511460da7a06616670d9506c77fb
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Aug 16 08:13:10 2023 +0200

    Port latest webconsole changes from main branch, use released artifacts, allow Java 11
---
 inventory/pom.xml                                  |   8 +-
 webconsole/pom.xml                                 |  30 +-
 .../felix/webconsole/AbstractWebConsolePlugin.java |  62 ----
 .../felix/webconsole/DefaultBrandingPlugin.java    |   5 +-
 .../felix/webconsole/WebConsoleConstants.java      |   1 -
 .../webconsole/WebConsoleSecurityProvider3.java    |   4 +-
 .../apache/felix/webconsole/WebConsoleUtil.java    | 107 +-----
 .../webconsole/internal/compendium/LogServlet.java |   2 +-
 .../internal/core/BundleContextUtil.java           |   8 +-
 .../webconsole/internal/core/BundlesServlet.java   | 406 +++++++--------------
 .../webconsole/internal/servlet/OsgiManager.java   |  18 +-
 .../felix/webconsole/internal/servlet/Plugin.java  |   3 +-
 12 files changed, 168 insertions(+), 486 deletions(-)

diff --git a/inventory/pom.xml b/inventory/pom.xml
index 621215535a..0466d0f565 100644
--- a/inventory/pom.xml
+++ b/inventory/pom.xml
@@ -22,13 +22,13 @@
     <parent>
         <groupId>org.apache.felix</groupId>
         <artifactId>felix-parent</artifactId>
-        <version>8-SNAPSHOT</version>
+	<version>7</version>
         <relativePath>../pom/pom.xml</relativePath>
     </parent>
 
     <artifactId>org.apache.felix.inventory</artifactId>
     <packaging>bundle</packaging>
-    <version>3.0.0-SNAPSHOT</version>
+    <version>2.0.0-SNAPSHOT</version>
 
     <name>Apache Felix Inventory</name>
     <description>Apache Felix Inventory provides some mechanisms to get the current state of the system and therefore provides an inventory of the system.</description>
@@ -41,7 +41,7 @@
     </scm>
 
     <properties>
-        <felix.java.version>17</felix.java.version>
+        <felix.java.version>11</felix.java.version>
     </properties>
 
     <build>
@@ -110,7 +110,7 @@
         <dependency>
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.service.servlet</artifactId>
-            <version>3.0.0-SNAPSHOT</version>
+            <version>2.0.0</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/webconsole/pom.xml b/webconsole/pom.xml
index 65aaa557ba..6e76474344 100644
--- a/webconsole/pom.xml
+++ b/webconsole/pom.xml
@@ -22,18 +22,18 @@
     <parent>
         <groupId>org.apache.felix</groupId>
         <artifactId>felix-parent</artifactId>
-        <version>8-SNAPSHOT</version>
+        <version>7</version>
         <relativePath>../pom/pom.xml</relativePath>
     </parent>
 
     <artifactId>org.apache.felix.webconsole</artifactId>
     <packaging>bundle</packaging>
-    <version>6.0.0-SNAPSHOT</version>
+    <version>5.0.0-SNAPSHOT</version>
 
     <name>Apache Felix Web Management Console</name>
     <description>
         Web Based Management Console for OSGi Frameworks. See
-        http://felix.apache.org/site/apache-felix-web-console.html for more
+        https://felix.apache.org/site/apache-felix-web-console.html for more
         information on this bundle.
     </description>
     
@@ -44,14 +44,13 @@
             org.apache.felix.webconsole.i18n;provide:=true,
             org.apache.felix.webconsole.spi
 	   </webconsole.exports>
-	   <felix.java.version>17</felix.java.version>
+	   <felix.java.version>11</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>
         <url>https://gitbox.apache.org/repos/asf?p=felix-dev.git</url>
-        <tag>org.apache.felix.webconsole-6.0.0</tag>
     </scm>
 
     <build>
@@ -95,7 +94,7 @@
             <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-bundle-plugin</artifactId>
-                <version>5.1.8</version>
+                <version>5.1.9</version>
                 <extensions>true</extensions>
                 <configuration>
                     <instructions>
@@ -227,8 +226,6 @@
                                            ${project.version}-all
                                        </Bundle-Version>
                                        <Export-Package>
-                                           org.apache.commons.fileupload2.core,
-                                           org.apache.commons.fileupload2.jakarta.servlet6,
                                            org.apache.commons.io.*,
                                            org.apache.felix.inventory,
                                            ${webconsole.exports}
@@ -238,8 +235,6 @@
                                            org.apache.felix.utils;inline=org/apache/felix/utils/manifest/**,
                                            org.apache.felix.utils;inline=org/apache/felix/utils/json/**,
                                            org.apache.felix.inventory;inline=true,
-                                           commons-fileupload2-core;inline=true,
-                                           commons-fileupload2-jakarta-servlet6;inline=true,
                                            commons-io;inline=true
                                        </Embed-Dependency>
                                        <_removeheaders>
@@ -274,7 +269,7 @@
                 <dependency>
                     <groupId>org.apache.felix</groupId>
                     <artifactId>org.apache.felix.inventory</artifactId>
-                    <version>3.0.0-SNAPSHOT</version>
+                    <version>2.0.0-SNAPSHOT</version>
                     <scope>provided</scope>
                 </dependency>
             </dependencies>
@@ -374,7 +369,7 @@
         <dependency>
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.service.servlet</artifactId>
-            <version>3.0.0-SNAPSHOT</version>
+            <version>2.0.0</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
@@ -389,16 +384,6 @@
             <version>6.0.0</version>
             <scope>provided</scope>
         </dependency>
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-fileupload2-core</artifactId>
-            <version>2.0.0-M3-SNAPSHOT</version>
-        </dependency>        
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-fileupload2-jakarta-servlet6</artifactId>
-            <version>2.0.0-M3-SNAPSHOT</version>
-        </dependency>        
         <dependency>
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>
@@ -434,7 +419,6 @@
             <scope>provided</scope>
             <optional>true</optional>
         </dependency>
-
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java b/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java
index 36f5af794b..097cf31625 100755
--- a/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java
@@ -67,26 +67,6 @@ public abstract class AbstractWebConsolePlugin extends HttpServlet
     /** Pseudo class version ID to keep the IDE quite. */
     private static final long serialVersionUID = 1L;
 
-    /** The name of the request attribute containing the map of FileItems from the POST request */
-    public static final String ATTR_FILEUPLOAD = "org.apache.felix.webconsole.fileupload"; //$NON-NLS-1$
-    
-    /** 
-     * The name of the request attribute containing a {@link java.io.File} - upload repository path used by
-     * {@link org.apache.commons.fileupload.disk.DiskFileItemFactory}.<p>
-     * 
-     * The Web Console plugin, that utilizes file upload capabilities of the web console SHOULD:
-     * <ol>
-     * <li>Obtain the file using {@link org.osgi.framework.BundleContext#getDataFile(String)}
-     * <li>Set the file as request attribute
-     * <li>Use {@link WebConsoleUtil#getParameter(HttpServletRequest, String)} to obtain the file(s)
-     * </ol>
-     * 
-     * Without setting this attribute, your plugin will not work if there is a security manager enabled.
-     * It is guaranteed, that your plugin has permissions to read/write/delete files to the location, 
-     * provided by the bundle context.
-     */
-    public static final String ATTR_FILEUPLOAD_REPO = "org.apache.felix.webconsole.fileupload.repo"; //$NON-NLS-1$
-
     /**
      * Web Console Plugin typically consists of servlet and resources such as images,
      * scripts or style sheets.
@@ -801,48 +781,6 @@ public abstract class AbstractWebConsolePlugin extends HttpServlet
         pw.println(getFooter());
     }
 
-
-    /**
-     * An utility method, that is used to filter out simple parameter from file
-     * parameter when multipart transfer encoding is used.
-     *
-     * This method processes the request and sets a request attribute
-     * {@link #ATTR_FILEUPLOAD}. The attribute value is a {@link Map}
-     * where the key is a String specifying the field name and the value
-     * is a {@link org.apache.commons.fileupload.FileItem}.
-     *
-     * @param request the HTTP request coming from the user
-     * @param name the name of the parameter
-     * @return if not multipart transfer encoding is used - the value is the
-     *  parameter value or <code>null</code> if not set. If multipart is used,
-     *  and the specified parameter is field - then the value of the parameter
-     *  is returned.
-     * @deprecated use {@link WebConsoleUtil#getParameter(HttpServletRequest, String)}
-     */
-    public static final String getParameter( HttpServletRequest request, String name )
-    {
-        return WebConsoleUtil.getParameter(request, name);
-    }
-
-    /**
-     * Utility method to handle relative redirects.
-     * Some application servers like Web Sphere handle relative redirects differently
-     * therefore we should make an absolute URL before invoking send redirect.
-     *
-     * @param request the HTTP request coming from the user
-     * @param response the HTTP response, where data is rendered
-     * @param redirectUrl the redirect URI.
-     * @throws IOException If an input or output exception occurs
-     * @throws IllegalStateException   If the response was committed or if a partial
-     *  URL is given and cannot be converted into a valid URL
-     * @deprecated use {@link WebConsoleUtil#sendRedirect(HttpServletRequest, HttpServletResponse, String)}
-     */
-    protected void sendRedirect(final HttpServletRequest request,
-                                final HttpServletResponse response,
-                                String redirectUrl) throws IOException {
-        WebConsoleUtil.sendRedirect(request, response, redirectUrl);
-    }
-
     /**
      * Returns the {@link BrandingPlugin} currently used for web console
      * branding.
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/DefaultBrandingPlugin.java b/webconsole/src/main/java/org/apache/felix/webconsole/DefaultBrandingPlugin.java
index 0a0a897f99..0da020b530 100755
--- a/webconsole/src/main/java/org/apache/felix/webconsole/DefaultBrandingPlugin.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/DefaultBrandingPlugin.java
@@ -32,7 +32,8 @@ import java.util.Properties;
  * <p>
  * This default implementation provides Apache Felix based default branding
  * as follows:
- * <table summary="Web Console Branding Properties">
+ * <table>
+ * <caption>Web Console Branding Properties</caption>
  * <tr><th>Name</th><th>Property Name</th><th>Default Value</th></tr>
  * <tr>
  *  <td>Brand Name</td>
@@ -47,7 +48,7 @@ import java.util.Properties;
  * <tr>
  *  <td>Product URL</td>
  *  <td>webconsole.product.url</td>
- *  <td>http://felix.apache.org</td>
+ *  <td>https://felix.apache.org</td>
  * </tr>
  * <tr>
  *  <td>Product Image</td>
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleConstants.java b/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleConstants.java
index 9b0e19aefc..bc09cf4d1c 100755
--- a/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleConstants.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleConstants.java
@@ -18,7 +18,6 @@
  */
 package org.apache.felix.webconsole;
 
-
 /**
  * WebConsoleConstants provides some common constants that are used by plugin
  * developers.
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleSecurityProvider3.java b/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleSecurityProvider3.java
index 1ffa19cff4..735e86d7fb 100755
--- a/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleSecurityProvider3.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleSecurityProvider3.java
@@ -21,6 +21,8 @@ package org.apache.felix.webconsole;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 
+import org.osgi.service.servlet.context.ServletContextHelper;
+
 /**
  * The <code>WebConsoleSecurityProvider3</code> extends the
  * {@link WebConsoleSecurityProvider2} interface and adds the ability to perform log-out operation.
@@ -32,7 +34,7 @@ import jakarta.servlet.http.HttpServletResponse;
  * If this service is missing and basic authentication is used, then new authentication is requested.
  * 
  * In any case, the logout procedure will invalidate the current session and will remove the 
- * {@link HttpContext#REMOTE_USER}, {@link HttpContext#AUTHORIZATION} attributes from the request and the session.
+ * {@link ServletContextHelper#REMOTE_USER}, {@link ServletContextHelper#AUTHORIZATION} attributes from the request and the session.
  * 
  * @since 4.2.8; Web Console Bundle 4.2.8
  */
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleUtil.java b/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleUtil.java
index 0ffab0a9d3..447d0ccd5b 100755
--- a/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleUtil.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleUtil.java
@@ -18,21 +18,10 @@
  */
 package org.apache.felix.webconsole;
 
-
-import java.io.File;
 import java.io.IOException;
+import java.io.UnsupportedEncodingException;
 import java.lang.reflect.Array;
 import java.net.URLDecoder;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.fileupload2.core.DiskFileItemFactory;
-import org.apache.commons.fileupload2.core.FileItem;
-import org.apache.commons.fileupload2.core.FileUploadException;
-import org.apache.commons.fileupload2.jakarta.servlet6.JakartaServletFileUpload;
-import org.apache.commons.fileupload2.jakarta.servlet6.JakartaServletRequestContext;
 
 import jakarta.servlet.ServletRequest;
 import jakarta.servlet.http.HttpServletRequest;
@@ -103,100 +92,6 @@ public final class WebConsoleUtil
         request.setAttribute( WebConsoleConstants.ATTR_CONSOLE_VARIABLE_RESOLVER, resolver );
     }
 
-
-    /**
-     * An utility method, that is used to filter out simple parameter from file
-     * parameter when multipart transfer encoding is used.
-     *
-     * This method processes the request and sets a request attribute
-     * {@link AbstractWebConsolePlugin#ATTR_FILEUPLOAD}. The attribute value is a {@link Map}
-     * where the key is a String specifying the field name and the value
-     * is a {@link org.apache.commons.fileupload.FileItem}.
-     *
-     * @param request the HTTP request coming from the user
-     * @param name the name of the parameter
-     * @return if not multipart transfer encoding is used - the value is the
-     *  parameter value or <code>null</code> if not set. If multipart is used,
-     *  and the specified parameter is field - then the value of the parameter
-     *  is returned.
-     */
-    public static final String getParameter( HttpServletRequest request, String name )
-    {
-        // just get the parameter if not a multipart/form-data POST
-        if ( !JakartaServletFileUpload.isMultipartContent( new JakartaServletRequestContext( request ) ) )
-        {
-            return request.getParameter( name );
-        }
-
-        // check, whether we already have the parameters
-        @SuppressWarnings("unchecked")
-        Map<String, FileItem[]> params = ( Map<String, FileItem[]> ) request.getAttribute( AbstractWebConsolePlugin.ATTR_FILEUPLOAD );
-        if ( params == null )
-        {
-            // parameters not read yet, read now
-            // Create a factory for disk-based file items
-            DiskFileItemFactory.Builder factoryBuilder = DiskFileItemFactory.builder();
-            factoryBuilder.setBufferSize( 256000 );
-            // See https://issues.apache.org/jira/browse/FELIX-4660
-            final Object repo = request.getAttribute( AbstractWebConsolePlugin.ATTR_FILEUPLOAD_REPO );
-            if ( repo instanceof File )
-            {
-                factoryBuilder.setPath( ((File) repo).toPath() );
-            }
-
-            // Create a new file upload handler
-            JakartaServletFileUpload upload = new JakartaServletFileUpload( factoryBuilder.get() );
-            upload.setSizeMax( -1 );
-            upload.setFileCountMax(50);
-
-            // Parse the request
-            params = new HashMap<>();
-            try
-            {
-                final List<FileItem> items = upload.parseRequest( request );
-                for ( final Iterator<FileItem> fiter = items.iterator(); fiter.hasNext(); )
-                {
-                    final FileItem fi = fiter.next();
-                    FileItem[] current = ( FileItem[] ) params.get( fi.getFieldName() );
-                    if ( current == null )
-                    {
-                        current = new FileItem[]
-                                { fi };
-                    }
-                    else
-                    {
-                        FileItem[] newCurrent = new FileItem[current.length + 1];
-                        System.arraycopy( current, 0, newCurrent, 0, current.length );
-                        newCurrent[current.length] = fi;
-                        current = newCurrent;
-                    }
-                    params.put( fi.getFieldName(), current );
-                }
-            }
-            catch ( FileUploadException fue )
-            {
-                // fail
-                return null;
-            }
-            request.setAttribute( AbstractWebConsolePlugin.ATTR_FILEUPLOAD, params );
-        }
-
-        FileItem[] param = ( FileItem[] ) params.get( name );
-        if ( param != null )
-        {
-            for ( int i = 0; i < param.length; i++ )
-            {
-                if ( param[i].isFormField() )
-                {
-                    return param[i].getString();
-                }
-            }
-        }
-
-        // no valid string parameter, fail
-        return null;
-    }
-
     /**
      * Utility method to handle relative redirects.
      * Some application servers like Web Sphere handle relative redirects differently
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/LogServlet.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/LogServlet.java
index 3c55ddd9e6..e3a2e147a8 100755
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/LogServlet.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/LogServlet.java
@@ -68,7 +68,7 @@ public class LogServlet extends SimpleWebConsolePlugin implements OsgiManagerPlu
      */
     protected void doPost( HttpServletRequest req, HttpServletResponse resp ) throws IOException
     {
-        final int minLevel = WebConsoleUtil.getParameterInt( req, "minLevel", LogService.LOG_DEBUG ); //$NON-NLS-1$
+        final int minLevel = WebConsoleUtil.getParameterInt( req, "minLevel", LogService.LOG_DEBUG); //$NON-NLS-1$
 
         resp.setContentType( "application/json" ); //$NON-NLS-1$
         resp.setCharacterEncoding( "utf-8" ); //$NON-NLS-1$
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundleContextUtil.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundleContextUtil.java
index 4148fe2e18..1202780daa 100755
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundleContextUtil.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundleContextUtil.java
@@ -24,8 +24,8 @@ import org.osgi.framework.Constants;
 /**
  * The <code>BundleContextUtil</code> class.
  */
-public class BundleContextUtil
-{
+public class BundleContextUtil {
+
     /**
      * This property defines which bundle context the web console plugins use to
      * get the list of bundles and services. It defaults to {@link #WORK_CTX_OWN}.
@@ -44,6 +44,8 @@ public class BundleContextUtil
     /**
      * Get the working bundle context: the bundle context to lookup bundles and
      * services.
+     * @param bc the bundle context of the web console plugin
+     * @return the bundle context to use
      */
     public static BundleContext getWorkingBundleContext( final BundleContext bc)
     {
@@ -53,4 +55,4 @@ public class BundleContextUtil
         }
         return bc;
     }
-}
\ No newline at end of file
+}
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
index d6599d8d37..1d3360bf96 100755
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
@@ -18,7 +18,10 @@ package org.apache.felix.webconsole.internal.core;
 
 
 import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.io.Writer;
@@ -27,6 +30,7 @@ import java.text.MessageFormat;
 import java.util.AbstractMap;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Comparator;
 import java.util.Date;
 import java.util.Dictionary;
@@ -43,11 +47,10 @@ import java.util.TreeMap;
 import java.util.jar.JarFile;
 import java.util.jar.Manifest;
 
-import org.apache.commons.fileupload2.core.FileItem;
+import org.apache.commons.io.IOUtils;
 import org.apache.felix.utils.json.JSONWriter;
 import org.apache.felix.utils.manifest.Clause;
 import org.apache.felix.utils.manifest.Parser;
-import org.apache.felix.webconsole.AbstractWebConsolePlugin;
 import org.apache.felix.webconsole.ConfigurationPrinter;
 import org.apache.felix.webconsole.DefaultVariableResolver;
 import org.apache.felix.webconsole.SimpleWebConsolePlugin;
@@ -79,7 +82,7 @@ import org.osgi.util.tracker.ServiceTrackerCustomizer;
 import jakarta.servlet.ServletException;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
-
+import jakarta.servlet.http.Part;
 
 /**
  * The <code>BundlesServlet</code> provides the bundles plugins, used to display
@@ -143,8 +146,7 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
      * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#activate(org.osgi.framework.BundleContext)
      */
     @Override
-    public void activate( BundleContext bundleContext )
-    {
+    public void activate( BundleContext bundleContext ) {
         super.activate( bundleContext );
 
         bundleInfoTracker = new ServiceTracker<>( bundleContext, BundleInfoProvider.class, new ServiceTrackerCustomizer<BundleInfoProvider,BundleInfoProvider>() {
@@ -357,20 +359,23 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
      * @see jakarta.servlet.http.HttpServlet#doPost(jakarta.servlet.http.HttpServletRequest, jakarta.servlet.http.HttpServletResponse)
      */
     @Override
-    protected void doPost( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException
-    {
+    protected void doPost( HttpServletRequest req, HttpServletResponse resp )
+    throws ServletException, IOException {
         boolean success = false;
         BundleException bundleException = null;
-        final String action = WebConsoleUtil.getParameter( req, "action" );
-        if ( "refreshPackages".equals( action ) )
-        {
+        final String action;
+        if (req.getParts().isEmpty()) {
+            action = req.getParameter( "action" );
+        } else {
+            action = getValue(req, "action");
+        }
+
+        if ( "refreshPackages".equals( action ) ) {
             // refresh packages and give it most 15 seconds to finish
             final FrameworkWiring fw = getBundleContext().getBundle(Constants.SYSTEM_BUNDLE_LOCATION).adapt(FrameworkWiring.class);
             BaseUpdateInstallHelper.refreshPackages( fw, getBundleContext(), 15000L, null );
             success = true;
-        }
-        else if ( "install".equals( action ) )
-        {
+        } else if ( "install".equals( action ) ) {
             installBundles( req );
 
             if (req.getRequestURI().endsWith( "/install" )) {
@@ -382,65 +387,43 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
             }
 
             return;
-        }
-        else
-        {
+        } else {
             final RequestInfo reqInfo = new RequestInfo( req );
-            if ( reqInfo.bundle == null && reqInfo.bundleRequested )
-            {
+            if ( reqInfo.bundle == null && reqInfo.bundleRequested ) {
                 resp.sendError( 404 );
                 return;
             }
 
             final Bundle bundle = reqInfo.bundle;
-            if ( bundle != null )
-            {
-                if ( "start".equals( action ) )
-                {
+            if ( bundle != null ) {
+                if ( "start".equals( action ) ) {
                     // start bundle
-                    try
-                    {
+                    try {
                         bundle.start();
-                    }
-                    catch ( BundleException be )
-                    {
+                    } catch ( BundleException be ) {
                         bundleException = be;
                         log( "Cannot start", be );
                     }
-                }
-                else if ( "stop".equals( action ) )
-                {
+                } else if ( "stop".equals( action ) ) {
                     // stop bundle
-                    try
-                    {
+                    try {
                         bundle.stop();
-                    }
-                    catch ( BundleException be )
-                    {
+                    } catch ( BundleException be ) {
                         bundleException = be;
                         log( "Cannot stop", be );
                     }
-                }
-                else if ( "refresh".equals( action ) )
-                {
+                } else if ( "refresh".equals( action ) ) {
                     // refresh bundle wiring and give at most 5 seconds to finish
                     final FrameworkWiring fw = getBundleContext().getBundle(Constants.SYSTEM_BUNDLE_LOCATION).adapt(FrameworkWiring.class);
                     BaseUpdateInstallHelper.refreshPackages( fw, getBundleContext(), 5000L, bundle );
-                }
-                else if ( "update".equals( action ) )
-                {
+                } else if ( "update".equals( action ) ) {
                     // update the bundle
                     update( bundle );
-                }
-                else if ( "uninstall".equals( action ) )
-                {
+                } else if ( "uninstall".equals( action ) ) {
                     // uninstall bundle
-                    try
-                    {
+                    try {
                         bundle.uninstall();
-                    }
-                    catch ( BundleException be )
-                    {
+                    } catch ( BundleException be ) {
                         bundleException = be;
                         log( "Cannot uninstall", be );
                     }
@@ -449,13 +432,10 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
                 // write the state only
                 resp.setContentType( "application/json" ); //$NON-NLS-1$
                 resp.setCharacterEncoding( "UTF-8" ); //$NON-NLS-1$
-                if ( null == getBundleContext() )
-                {
+                if ( null == getBundleContext() ) {
                     // refresh package on the web console itself or some of it's dependencies
                     resp.getWriter().print("false"); //$NON-NLS-1$
-                }
-                else
-                {
+                } else {
                     resp.getWriter().print( "{\"fragment\":" + isFragmentBundle( bundle ) //$NON-NLS-1$
                     + ",\"stateRaw\":" + bundle.getState() + "}" ); //$NON-NLS-1$ //$NON-NLS-2$
                 }
@@ -463,27 +443,20 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
             }
         }
 
-        if ( success && null != getBundleContext() )
-        {
+        if ( success && null != getBundleContext() ) {
             final String pluginRoot = ( String ) req.getAttribute( WebConsoleConstants.ATTR_PLUGIN_ROOT );
             final String servicesRoot = getServicesRoot( req );
-            try
-            {
+            try {
                 this.renderJSON( resp, null, pluginRoot, servicesRoot, req.getLocale(), req.getParameter(FILTER_PARAM), bundleException );
-            }
-            catch (InvalidSyntaxException e)
-            {
+            } catch (InvalidSyntaxException e) {
                 resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Invalid LDAP filter specified");
             }
-        }
-        else
-        {
+        } else {
             super.doPost( req, resp );
         }
     }
 
-    private String getServicesRoot(HttpServletRequest request)
-    {
+    private String getServicesRoot(HttpServletRequest request) {
         return ( ( String ) request.getAttribute( WebConsoleConstants.ATTR_APP_ROOT ) ) +
                 "/" + ServicesServlet.LABEL + "/";
     }
@@ -518,14 +491,11 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
 
             // search
             final Bundle[] bundles = BundleContextUtil.getWorkingBundleContext(this.getBundleContext()).getBundles();
-            for(int i=0; i<bundles.length; i++)
-            {
+            for(int i=0; i<bundles.length; i++) {
                 final Bundle bundle = bundles[i];
                 // check symbolic name first
-                if ( symbolicName.equals(bundle.getSymbolicName()) )
-                {
-                    if ( version == null || version.equals(bundle.getHeaders().get(Constants.BUNDLE_VERSION)) )
-                    {
+                if ( symbolicName.equals(bundle.getSymbolicName()) ) {
+                    if ( version == null || version.equals(bundle.getHeaders().get(Constants.BUNDLE_VERSION)) ) {
                         return bundle;
                     }
                 }
@@ -537,8 +507,7 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
     }
 
 
-    private void appendBundleInfoCount( final StringBuilder buf, String msg, int count )
-    {
+    private void appendBundleInfoCount( final StringBuilder buf, String msg, int count ) {
         buf.append(count);
         buf.append(" bundle");
         if ( count != 1 )
@@ -551,6 +520,7 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
      * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#renderContent(jakarta.servlet.http.HttpServletRequest, jakarta.servlet.http.HttpServletResponse)
      */
     @Override
+    @SuppressWarnings("unchecked")
     protected void renderContent( HttpServletRequest request, HttpServletResponse response ) throws IOException
     {
         // get request info from request attribute
@@ -904,7 +874,7 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
             StartLevel sl = getStartLevel();
             if ( sl != null )
             {
-                return new Integer( sl.getBundleStartLevel( bundle ) );
+                return sl.getBundleStartLevel( bundle );
             }
         }
 
@@ -913,7 +883,7 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
     }
 
 
-    private void listImportExport( List props, Bundle bundle, final String pluginRoot )
+    private void listImportExport( List<Map<String, Object>> props, Bundle bundle, final String pluginRoot )
     {
         PackageAdmin packageAdmin = getPackageAdmin();
         if ( packageAdmin == null )
@@ -921,24 +891,15 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
             return;
         }
 
-        Map usingBundles = new TreeMap();
+        Map<String, Bundle> usingBundles = new TreeMap<>();
 
         ExportedPackage[] exports = packageAdmin.getExportedPackages( bundle );
-        if ( exports != null && exports.length > 0 )
-        {
+        if ( exports != null && exports.length > 0 ) {
             // do alphabetical sort
-            Arrays.sort( exports, new Comparator()
-            {
-                public int compare( ExportedPackage p1, ExportedPackage p2 )
-                {
-                    return p1.getName().compareTo( p2.getName() );
-                }
-
-
+            Arrays.sort( exports, new Comparator<ExportedPackage>() {
                 @Override
-                public int compare( Object o1, Object o2 )
-                {
-                    return compare( ( ExportedPackage ) o1, ( ExportedPackage ) o2 );
+                public int compare( ExportedPackage p1, ExportedPackage p2 ) {
+                    return p1.getName().compareTo( p2.getName() );
                 }
             } );
 
@@ -970,7 +931,7 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
         if ( exports != null && exports.length > 0 )
         {
             // collect import packages first
-            final List imports = new ArrayList();
+            final List<ExportedPackage> imports = new ArrayList<>();
             for ( int i = 0; i < exports.length; i++ )
             {
                 final ExportedPackage ep = exports[i];
@@ -987,34 +948,21 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
             }
             // now sort
             Object[] val;
-            if ( imports.size() > 0 )
-            {
-                final ExportedPackage[] packages = ( ExportedPackage[] ) imports.toArray( new ExportedPackage[imports
-                                                                                                              .size()] );
-                Arrays.sort( packages, new Comparator()
-                {
-                    public int compare( ExportedPackage p1, ExportedPackage p2 )
-                    {
-                        return p1.getName().compareTo( p2.getName() );
-                    }
-
-
+            if ( imports.size() > 0 ) {
+                final ExportedPackage[] packages = ( ExportedPackage[] ) imports.toArray( new ExportedPackage[imports.size()] );
+                Arrays.sort( packages, new Comparator<ExportedPackage>() {
                     @Override
-                    public int compare( Object o1, Object o2 )
-                    {
-                        return compare( ( ExportedPackage ) o1, ( ExportedPackage ) o2 );
+                    public int compare( ExportedPackage p1, ExportedPackage p2 ) {
+                        return p1.getName().compareTo( p2.getName() );
                     }
                 } );
                 // and finally print out
                 val = new Object[packages.length];
-                for ( int i = 0; i < packages.length; i++ )
-                {
+                for ( int i = 0; i < packages.length; i++ ) {
                     ExportedPackage ep = packages[i];
                     val[i] = collectImport( ep.getName(), ep.getVersion(), false, ep, pluginRoot );
                 }
-            }
-            else
-            {
+            } else {
                 // add description if there are no imports
                 val = new Object[1];
                 val[0] =  "None";
@@ -1023,13 +971,10 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
             keyVal( props, "Imported Packages", val );
         }
 
-        if ( !usingBundles.isEmpty() )
-        {
+        if ( !usingBundles.isEmpty() ) {
             Object[] val = new Object[usingBundles.size()];
             int index = 0;
-            for ( Iterator ui = usingBundles.values().iterator(); ui.hasNext(); )
-            {
-                Bundle usingBundle = ( Bundle ) ui.next();
+            for(final Bundle usingBundle : usingBundles.values()) {
                 val[index] = getBundleDescriptor( usingBundle, pluginRoot );
                 index++;
             }
@@ -1038,30 +983,20 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
     }
 
 
-    private void listImportExportsUnresolved( final List props, Bundle bundle, final String pluginRoot )
-    {
-        Dictionary dict = bundle.getHeaders();
+    private void listImportExportsUnresolved( final List<Map<String, Object>> props, Bundle bundle, final String pluginRoot ) {
+        final Dictionary<String, String> dict = bundle.getHeaders();
 
         String target = ( String ) dict.get( Constants.EXPORT_PACKAGE );
-        if ( target != null )
-        {
+        if ( target != null ) {
             Clause[] pkgs = Parser.parseHeader( target );
-            if ( pkgs != null && pkgs.length > 0 )
-            {
+            if ( pkgs != null && pkgs.length > 0 ) {
                 // do alphabetical sort
-                Arrays.sort( pkgs, new Comparator()
-                {
+                Arrays.sort( pkgs, new Comparator<Clause>() {
+                    @Override
                     public int compare( Clause p1, Clause p2 )
                     {
                         return p1.getName().compareTo( p2.getName() );
                     }
-
-
-                    @Override
-                    public int compare( Object o1, Object o2 )
-                    {
-                        return compare( ( Clause) o1, ( Clause ) o2 );
-                    }
                 } );
 
                 Object[] val = new Object[pkgs.length];
@@ -1084,7 +1019,7 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
             Clause[] pkgs = Parser.parseHeader( target );
             if ( pkgs != null && pkgs.length > 0 )
             {
-                Map imports = new TreeMap();
+                Map<String, Clause> imports = new TreeMap<>();
                 for ( int i = 0; i < pkgs.length; i++ )
                 {
                     Clause pkg = pkgs[i];
@@ -1092,7 +1027,7 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
                 }
 
                 // collect import packages first
-                final Map candidates = new HashMap();
+                final Map<String, ExportedPackage> candidates = new HashMap<>();
                 PackageAdmin packageAdmin = getPackageAdmin();
                 if ( packageAdmin != null )
                 {
@@ -1152,7 +1087,7 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
         }
     }
 
-    private String getServiceID(ServiceReference ref, final String servicesRoot)
+    private String getServiceID(ServiceReference<?> ref, final String servicesRoot)
     {
         String id = ref.getProperty( Constants.SERVICE_ID ).toString();
 
@@ -1169,9 +1104,9 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
     }
 
 
-    private void listServices( List props, Bundle bundle, final String servicesRoot )
+    private void listServices( List<Map<String, Object>> props, Bundle bundle, final String servicesRoot )
     {
-        ServiceReference[] refs = bundle.getRegisteredServices();
+        ServiceReference<?>[] refs = bundle.getRegisteredServices();
         if ( refs == null || refs.length == 0 )
         {
             return;
@@ -1183,7 +1118,7 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
 
             String key = "Service ID " + getServiceID( refs[i], servicesRoot );
 
-            List val = new ArrayList();
+            List<String> val = new ArrayList<>();
 
             appendProperty( val, refs[i], Constants.OBJECTCLASS, "Types" );
             appendProperty( val, refs[i], Constants.SERVICE_PID, "Service PID" );
@@ -1195,28 +1130,27 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
             appendProperty( val, refs[i], Constants.SERVICE_DESCRIPTION, "Description" );
             appendProperty( val, refs[i], Constants.SERVICE_VENDOR, "Vendor" );
 
-            keyVal( props, key, val.toArray(new Object[val.size()]));
+            keyVal( props, key, val.toArray(new String[val.size()]));
         }
     }
 
 
-    private void listHeaders( List props, Bundle bundle )
+    private void listHeaders( List<Map<String, Object>> props, Bundle bundle )
     {
-        List val = new ArrayList();
+        final List<String> val = new ArrayList<>();
 
-        Dictionary headers = bundle.getHeaders(""); // don't localize at all - raw headers
-        Enumeration he = headers.keys();
-        while ( he.hasMoreElements() )
-        {
-            Object header = he.nextElement();
-            String value = String.valueOf(headers.get( header ));
+        final Dictionary<String, String> headers = bundle.getHeaders(""); // don't localize at all - raw headers
+        final Enumeration<String> he = headers.keys();
+        while ( he.hasMoreElements() ) {
+            final String header = he.nextElement();
+            String value = headers.get( header );
             // Package headers may be long, support line breaking by
             // ensuring blanks after comma and semicolon.
             value = enableLineWrapping(value);
             val.add( header + ": " + value );
         }
 
-        keyVal( props, "Manifest Headers", val.toArray(new Object[val.size()]) );
+        keyVal( props, "Manifest Headers", val.toArray(new String[val.size()]) );
     }
 
     private static final String enableLineWrapping(final String value)
@@ -1234,7 +1168,7 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
         return sb.toString();
     }
 
-    private void listFragmentInfo( final List props, final Bundle bundle, final String pluginRoot )
+    private void listFragmentInfo( final List<Map<String, Object>> props, final Bundle bundle, final String pluginRoot )
     {
 
         if ( isFragmentBundle( bundle ) )
@@ -1267,7 +1201,7 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
     }
 
 
-    private void appendProperty( final List props, ServiceReference ref, String name, String label )
+    private void appendProperty( final List<String> props, ServiceReference<?> ref, String name, String label )
     {
         StringBuilder dest = new StringBuilder();
         Object value = ref.getProperty( name );
@@ -1543,35 +1477,33 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
 
     //---------- Bundle Installation handler (former InstallAction)
 
-    private void installBundles( HttpServletRequest request ) throws IOException
-    {
-
-        // get the uploaded data
-        final Map params = ( Map ) request.getAttribute( AbstractWebConsolePlugin.ATTR_FILEUPLOAD );
-        if ( params == null )
-        {
+    private String getValue(final HttpServletRequest request, final String fieldName) throws ServletException, IOException {
+        final Part part = request.getPart(fieldName);
+        if ( part != null ) {
+            return IOUtils.toString(part.getInputStream(), "UTF-8");
+        }
+        return null;
+    }
+    
+    private void installBundles( final HttpServletRequest request )
+    throws IOException, ServletException {
+        final Collection<Part> bundleItems = request.getParts();
+        if ( bundleItems.isEmpty() ) {
             return;
         }
 
         final long uploadId;
-        final String uidVal = WebConsoleUtil.getParameter( request, "uploadid" );
+        final String uidVal = this.getValue(request, "uploadid");
         if ( uidVal != null ) {
             uploadId = Long.valueOf(uidVal);
         } else {
             uploadId = -1;
         }
 
-        final FileItem startItem = getParameter( params, FIELD_START );
-        final FileItem startLevelItem = getParameter( params, FIELD_STARTLEVEL );
-        final FileItem[] bundleItems = getFileItems( params, FIELD_BUNDLEFILE );
-        final FileItem refreshPackagesItem = getParameter( params, FIELD_REFRESH_PACKAGES );
-        final FileItem parallelVersionItem = getParameter( params, FIELD_PARALLEL_VERSION );
-
-        // don't care any more if no bundle item
-        if ( bundleItems.length == 0 )
-        {
-            return;
-        }
+        final String startItem = this.getValue(request, FIELD_START);
+        final String startLevelItem = this.getValue(request, FIELD_STARTLEVEL);
+        final String refreshPackagesItem = this.getValue(request, FIELD_REFRESH_PACKAGES);
+        final String parallelVersionItem = this.getValue(request, FIELD_PARALLEL_VERSION);
 
         // default values
         // it exists
@@ -1579,96 +1511,51 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
         String bundleLocation = "inputstream:";
 
         // convert the start level value
-        if ( startLevelItem != null )
-        {
-            try
-            {
-                startLevel = Integer.parseInt( startLevelItem.getString() );
-            }
-            catch ( NumberFormatException nfe )
-            {
+        if ( startLevelItem != null ) {
+            try {
+                startLevel = Integer.parseInt( startLevelItem );
+            } catch ( NumberFormatException nfe ) {
                 log( LogService.LOG_INFO, "Cannot parse start level parameter " + startLevelItem
                         + " to a number, not setting start level" );
             }
         }
 
-        for ( int i = 0; i < bundleItems.length; i++ )
-        {
-            final FileItem bundleItem = bundleItems[i];
+        for(final Part part : bundleItems) {
+            if (!FIELD_BUNDLEFILE.equals(part.getName())) {
+                continue;
+            }
             // write the bundle data to a temporary file to ease processing
             File tmpFile = null;
-            try
-            {
+            try {
                 // copy the data to a file for better processing
                 tmpFile = File.createTempFile( "install", ".tmp" );
-                tmpFile.delete(); // FIX for FILEUPLOAD-293
-                bundleItem.write( tmpFile );
-            }
-            catch ( Exception e )
-            {
-                log( LogService.LOG_ERROR, "Problem accessing uploaded bundle file: " + bundleItem.getName(), e );
+                try (final InputStream bundleStream = part.getInputStream();
+                     final OutputStream out = new FileOutputStream(tmpFile)) {
+                    IOUtils.copy(bundleStream, out);
+                }
+            } catch ( final Exception e ) {
+                log( LogService.LOG_ERROR, "Problem accessing uploaded bundle file: " + part.getName(), e );
 
                 // remove the tmporary file
-                if ( tmpFile != null )
-                {
+                if ( tmpFile != null && tmpFile.exists()) {
                     tmpFile.delete();
                     tmpFile = null;
                 }
             }
 
             // install or update the bundle now
-            if ( tmpFile != null )
-            {
+            if ( tmpFile != null ) {
                 // start, refreshPackages just needs to exist, don't care for value
                 final boolean start = startItem != null;
                 final boolean refreshPackages = refreshPackagesItem != null;
                 final boolean parallelVersion = parallelVersionItem != null;
 
-                bundleLocation = "inputstream:" + bundleItem.getName();
+                bundleLocation = "inputstream:".concat(part.getName());
                 installBundle( bundleLocation, tmpFile, startLevel, start, refreshPackages, parallelVersion, uploadId);
             }
         }
     }
 
-
-    private FileItem getParameter( Map params, String name )
-    {
-        FileItem[] items = ( FileItem[] ) params.get( name );
-        if ( items != null )
-        {
-            for ( int i = 0; i < items.length; i++ )
-            {
-                if ( items[i].isFormField() )
-                {
-                    return items[i];
-                }
-            }
-        }
-
-        // nothing found, fail
-        return null;
-    }
-
-
-    private FileItem[] getFileItems( Map params, String name )
-    {
-        final List files = new ArrayList();
-        FileItem[] items = ( FileItem[] ) params.get( name );
-        if ( items != null )
-        {
-            for ( int i = 0; i < items.length; i++ )
-            {
-                if ( !items[i].isFormField() && items[i].getSize() > 0 )
-                {
-                    files.add( items[i] );
-                }
-            }
-        }
-
-        return ( FileItem[] ) files.toArray( new FileItem[files.size()] );
-    }
-
-
     private void installBundle( String location, File bundleFile, int startLevel, boolean start, boolean refreshPackages, boolean parallelVersion, final long uploadId)
     throws IOException
     {
@@ -1721,48 +1608,29 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
         }
     }
 
-
-    private String getSymbolicName( File bundleFile )
-    {
-        return  getSymbolicNameVersion(bundleFile).getKey();
-    }
-
-    private Map.Entry<String, String> getSymbolicNameVersion( File bundleFile )
-    {
+    private Map.Entry<String, String> getSymbolicNameVersion( File bundleFile ) {
         JarFile jar = null;
-        try
-        {
+        try {
             jar = new JarFile( bundleFile );
-            Manifest m = jar.getManifest();
-            if ( m != null )
-            {
+            final Manifest m = jar.getManifest();
+            if ( m != null ) {
                 String sn = m.getMainAttributes().getValue( Constants.BUNDLE_SYMBOLICNAME );
-                if ( sn != null )
-                {
+                if ( sn != null ) {
                     final int paramPos = sn.indexOf(';');
-                    if ( paramPos != -1 )
-                    {
+                    if ( paramPos != -1 ) {
                         sn = sn.substring(0, paramPos);
                     }
                 }
-                String v = m.getMainAttributes().getValue( Constants.BUNDLE_VERSION );
-                return new AbstractMap.SimpleImmutableEntry(sn, v);
+                final String v = m.getMainAttributes().getValue( Constants.BUNDLE_VERSION );
+                return new AbstractMap.SimpleImmutableEntry<>(sn, v);
             }
-        }
-        catch ( IOException ioe )
-        {
+        } catch ( final IOException ioe ) {
             log( LogService.LOG_WARNING, "Cannot extract symbolic name and version of bundle file " + bundleFile, ioe );
-        }
-        finally
-        {
-            if ( jar != null )
-            {
-                try
-                {
+        } finally {
+            if ( jar != null ) {
+                try {
                     jar.close();
-                }
-                catch ( IOException ioe )
-                {
+                } catch ( IOException ioe ) {
                     // ignore
                 }
             }
@@ -1772,21 +1640,15 @@ public class BundlesServlet extends SimpleWebConsolePlugin implements OsgiManage
         return null;
     }
 
-
-
-
     private void installBackground( final File bundleFile, final String location, final int startlevel,
-            final boolean doStart, final boolean refreshPackages )
-    {
+            final boolean doStart, final boolean refreshPackages ) {
 
         InstallHelper t = new InstallHelper( this, getBundleContext(), bundleFile, location, startlevel, doStart,
                 refreshPackages );
         t.start();
     }
 
-
-    private void updateBackground( final Bundle bundle, final File bundleFile, final boolean refreshPackages )
-    {
+    private void updateBackground( final Bundle bundle, final File bundleFile, final boolean refreshPackages ) {
         UpdateHelper t = new UpdateHelper( this, bundle, bundleFile, refreshPackages );
         t.start();
     }
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
index 917a60e087..758935eb3d 100755
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
@@ -265,19 +265,19 @@ public class OsgiManager extends GenericServlet {
     private volatile Map<String, Object> configuration;
 
     // See https://issues.apache.org/jira/browse/FELIX-2267
-    private Locale configuredLocale;
+    private volatile Locale configuredLocale;
 
-    private Set<String> enabledPlugins;
+    private volatile Set<String> enabledPlugins;
 
     final ConcurrentSkipListSet<String> registeredSecurityProviders = new ConcurrentSkipListSet<String>();
 
     final Set<String> requiredSecurityProviders;
 
-    ResourceBundleManager resourceBundleManager;
+    final ResourceBundleManager resourceBundleManager;
 
-    private int logLevel = DEFAULT_LOG_LEVEL;
+    private volatile int logLevel = DEFAULT_LOG_LEVEL;
 
-    private String defaultCategory = DEFAULT_CATEGORY;
+    private volatile String defaultCategory = DEFAULT_CATEGORY;
 
     public OsgiManager(BundleContext bundleContext)
     {
@@ -437,11 +437,7 @@ public class OsgiManager extends GenericServlet {
         holder.close();
 
         // dispose off the resource bundle manager
-        if (resourceBundleManager != null)
-        {
-            resourceBundleManager.dispose();
-            resourceBundleManager = null;
-        }
+        resourceBundleManager.dispose();
 
         // stop listening for brandings
         if (brandingTracker != null)
@@ -934,6 +930,8 @@ public class OsgiManager extends GenericServlet {
                     props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_TARGET, httpServiceSelector);
                 }
 
+                props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_MULTIPART_ENABLED, Boolean.TRUE);
+                props.put("osgi.http.whiteboard.servlet.multipart.maxFileCount", 50);
                 props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/");
                 props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=" + SERVLEXT_CONTEXT_NAME + ")");
 
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/Plugin.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/Plugin.java
index d0463a3b5b..67c181c4ef 100755
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/Plugin.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/Plugin.java
@@ -69,6 +69,7 @@ public abstract class Plugin implements ServletConfig, Comparable<Plugin> {
 
     /**
      * Initialize everything including title and category
+     * @return {@code true} if the plugin is initialized, {@code false} otherwise
      */
     public boolean init() {
         final AbstractWebConsolePlugin plugin = this.doGetConsolePlugin();
@@ -169,7 +170,7 @@ public abstract class Plugin implements ServletConfig, Comparable<Plugin> {
     }
 
     @Override
-    public Enumeration getInitParameterNames() {
+    public Enumeration<String> getInitParameterNames() {
         return Collections.emptyEnumeration();
     }