#23507 Fixed signing jars downloaded by the appclient - several bugs

- reproducible by several tests enabled in recent commits
- removed incorrect wrapping of zip into zip
- fixed error message, reported input file as an output
- fixed closing streams
- fixed removing corrupted files (stream could be still open)
- fixed behavior when the glassfish-acc.xml file is missing
diff --git a/appserver/appclient/server/core/src/main/java/org/glassfish/appclient/server/core/jws/JWSAdapterManager.java b/appserver/appclient/server/core/src/main/java/org/glassfish/appclient/server/core/jws/JWSAdapterManager.java
index 0b0eaea..ca09031 100644
--- a/appserver/appclient/server/core/src/main/java/org/glassfish/appclient/server/core/jws/JWSAdapterManager.java
+++ b/appserver/appclient/server/core/src/main/java/org/glassfish/appclient/server/core/jws/JWSAdapterManager.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022 Contributors to the Eclipse Foundation
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -17,9 +18,12 @@
 package org.glassfish.appclient.server.core.jws;
 
 import com.sun.enterprise.config.serverbeans.Config;
-import org.glassfish.orb.admin.config.IiopService;
 import com.sun.enterprise.deployment.ApplicationClientDescriptor;
-import com.sun.logging.LogDomains;
+
+import jakarta.inject.Inject;
+import jakarta.inject.Named;
+import jakarta.inject.Singleton;
+
 import java.io.File;
 import java.io.FileFilter;
 import java.io.FileNotFoundException;
@@ -38,8 +42,7 @@
 import java.util.jar.Manifest;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import jakarta.inject.Inject;
-import jakarta.inject.Named;
+
 import org.glassfish.api.admin.ServerEnvironment;
 import org.glassfish.api.container.EndpointRegistrationException;
 import org.glassfish.api.container.RequestDispatcher;
@@ -52,12 +55,11 @@
 import org.glassfish.appclient.server.core.jws.servedcontent.SimpleDynamicContentImpl;
 import org.glassfish.appclient.server.core.jws.servedcontent.StaticContent;
 import org.glassfish.enterprise.iiop.api.GlassFishORBFactory;
-import org.glassfish.internal.api.ServerContext;
-
-import org.jvnet.hk2.annotations.Service;
 import org.glassfish.hk2.api.PostConstruct;
-import jakarta.inject.Singleton;
+import org.glassfish.internal.api.ServerContext;
 import org.glassfish.logging.annotation.LogMessageInfo;
+import org.glassfish.orb.admin.config.IiopService;
+import org.jvnet.hk2.annotations.Service;
 
 /**
  * Handles all management of the HTTP adapters created to support Java Web
@@ -98,39 +100,35 @@
 
     private static final String LINE_SEP = System.getProperty("line.separator");
 
-    private static final List<String> DO_NOT_SERVE_LIST =
-            Collections.EMPTY_LIST; //Arrays.asList("glassfish/modules/jaxb-osgi.jar");
+    private static final List<String> DO_NOT_SERVE_LIST = Collections.emptyList();
 
     private static final String JWS_SIGNED_SYSTEM_JARS_ROOT = "java-web-start/___system";
     private static final String JWS_SIGNED_DOMAIN_JARS_ROOT = "java-web-start/___domain";
 
-    private static final String JAVA_WEB_START_CONTEXT_ROOT_PROPERTY_NAME =
-            "javaWebStartContextRoot";
+    private static final String JAVA_WEB_START_CONTEXT_ROOT_PROPERTY_NAME = "javaWebStartContextRoot";
+
     /**
      * maps "(aliasName)/(systemJarRelativePath)" to AutoSignedContent for
      * the system JAR as signed by the cert linked to the alias
      */
-    private final Map<String,AutoSignedContent> appLevelSignedSystemContent =
-            new HashMap<String,AutoSignedContent>();
+    private final Map<String, AutoSignedContent> appLevelSignedSystemContent = new HashMap<>();
 
-    private URI installRootURI = null;
+    private URI installRootURI;
 
-    private AppClientHTTPAdapter systemAdapter = null;
+    private AppClientHTTPAdapter systemAdapter;
 
-    private Logger logger = null;
+    private Logger logger;
 
     private IiopService iiopService;
 
-    private final HashMap<String,Set<AppClientServerApplication>> contributingAppClients =
-            new HashMap<String,Set<AppClientServerApplication>>();
+    private final HashMap<String, Set<AppClientServerApplication>> contributingAppClients = new HashMap<>();
 
-    private final ConcurrentHashMap<String,AppClientHTTPAdapter> httpAdapters = new
-            ConcurrentHashMap<String, AppClientHTTPAdapter>();
+    private final ConcurrentHashMap<String, AppClientHTTPAdapter> httpAdapters = new ConcurrentHashMap<>();
 
-    private URI umbrellaRootURI = null;
-    private File umbrellaRoot = null;
-    private File systemLevelSignedJARsRoot = null;
-    private File domainLevelSignedJARsRoot = null;
+    private URI umbrellaRootURI;
+    private File umbrellaRoot;
+    private File systemLevelSignedJARsRoot;
+    private File domainLevelSignedJARsRoot;
 
     @LogMessageInfo(
             message = "Error starting the adapter to serve static system-level content",
@@ -227,7 +225,7 @@
          * adapter which serves files from the installation, as opposed to
          * files from the domain or files from a specific app.
          */
-        Map<String,StaticContent> result = new HashMap<String,StaticContent>();
+        Map<String,StaticContent> result = new HashMap<>();
         File gfClientJAR = gfClientJAR();
 
         final String classPathExpr = getGFClientModuleClassPath(gfClientJAR);
@@ -277,39 +275,39 @@
         return result;
     }
 
+
     File gfClientJAR() {
-        return new File(
-            libDir(),
-            "gf-client.jar");
+        return new File(libDir(), "gf-client.jar");
     }
 
+
     File gfClientModuleJAR() {
-        return new File(
-            modulesDir(),
-            "gf-client-module.jar");
+        return new File(modulesDir(), "gf-client-module.jar");
     }
 
+
     private synchronized File modulesDir() {
         return new File(new File(installRootURI), "modules");
     }
 
+
     private synchronized File libDir() {
         return new File(new File(installRootURI), "lib");
     }
 
-    private AutoSignedContent systemJarSignedContent (
-            final File unsignedFile,
-            final String signingAlias) throws FileNotFoundException {
+
+    private AutoSignedContent systemJarSignedContent(final File unsignedFile, final String signingAlias)
+        throws FileNotFoundException {
         final String relativeURI = relativeSystemPath(unsignedFile.toURI());
-        final File signedFile = new File(signedSystemContentAliasDir(signingAlias),
-                relativeURI);
+        final File signedFile = new File(signedSystemContentAliasDir(signingAlias), relativeURI);
         return new AutoSignedContent(unsignedFile, signedFile, signingAlias, jarSigner, relativeURI,
                 MANIFEST_APP_NAME_FOR_SYSTEM_FILES);
     }
 
-    Map<String,DynamicContent> addDynamicSystemContent(final List<String> systemJARRelativeURIs,
-            final String signingAlias) throws IOException {
-        final Map<String,DynamicContent> result = new HashMap<String,DynamicContent>();
+
+    Map<String, DynamicContent> addDynamicSystemContent(final List<String> systemJARRelativeURIs,
+        final String signingAlias) throws IOException {
+        final Map<String,DynamicContent> result = new HashMap<>();
         final String template = JavaWebStartInfo.textFromURL(
                 "/org/glassfish/appclient/server/core/jws/templates/systemJarsDocumentTemplate.jnlp");
         final StringBuilder sb = new StringBuilder();
@@ -328,8 +326,7 @@
     }
 
     private String systemPath(final URI systemFileURI) {
-        return //NamingConventions.JWSAPPCLIENT_SYSTEM_PREFIX + "/" +
-                relativeSystemPath(systemFileURI);
+        return relativeSystemPath(systemFileURI);
     }
 
     String systemPath(final URI systemFileURI, final String signingAlias) {
@@ -546,23 +543,16 @@
 
     public String contextRootForAppAdapter(final String appName) {
         final AppClientHTTPAdapter adapter = httpAdapters.get(appName);
-        if (adapter != null) {
-            return adapter.contextRoot();
-        } else {
-            return null;
-        }
+        return adapter == null ? null : adapter.contextRoot();
     }
 
-    private synchronized void addContributorToAppLevelAdapter(
-            final String appName,
-            final AppClientServerApplication contributor) {
-        /*
-         * Record that the calling app client server app has contributed content
-         * to the Grizzly adapter.
-         */
+
+    private synchronized void addContributorToAppLevelAdapter(final String appName,
+        final AppClientServerApplication contributor) {
+        // Record that the calling app client server app has contributed content to the Grizzly adapter.
         Set<AppClientServerApplication> contributorsToAppLevelAdapter = contributingAppClients.get(appName);
         if (contributorsToAppLevelAdapter == null) {
-            contributorsToAppLevelAdapter = new HashSet<AppClientServerApplication>();
+            contributorsToAppLevelAdapter = new HashSet<>();
             contributingAppClients.put(appName, contributorsToAppLevelAdapter);
         }
         contributorsToAppLevelAdapter.add(contributor);
@@ -572,13 +562,9 @@
             final String clientURIWithinEAR,
             final AppClientServerApplication contributor) throws EndpointRegistrationException {
 
-        /*
-         * Remove the adapter for the user-friendly context root.
-         */
+        // Remove the adapter for the user-friendly context root.
         removeAdapter(userFriendlyContextRoot(contributor));
-
         removeContributorToAppLevelAdapter(appName, contributor);
-
         appClientDeployer.removeContextRoot(appName, clientURIWithinEAR);
     }
 
@@ -602,21 +588,17 @@
         }
     }
 
-    private synchronized void removeAdapter(final String contextRoot)
-            throws EndpointRegistrationException {
+
+    private synchronized void removeAdapter(final String contextRoot) throws EndpointRegistrationException {
         requestDispatcher.unregisterEndpoint(contextRoot);
     }
 
-    private String getGFClientModuleClassPath(final File gfClientJAR) throws IOException {
-        final JarFile jf = new JarFile(gfClientJAR);
 
-        try {
-          final Manifest mf = jf.getManifest();
-          Attributes mainAttrs = mf.getMainAttributes();
-          return mainAttrs.getValue(Attributes.Name.CLASS_PATH);
-        } finally
-        {
-          jf.close();
+    private String getGFClientModuleClassPath(final File gfClientJAR) throws IOException {
+        try (JarFile jf = new JarFile(gfClientJAR)) {
+            final Manifest mf = jf.getManifest();
+            Attributes mainAttrs = mf.getMainAttributes();
+            return mainAttrs.getValue(Attributes.Name.CLASS_PATH);
         }
     }
 
diff --git a/appserver/appclient/server/core/src/main/java/org/glassfish/appclient/server/core/jws/JavaWebStartInfo.java b/appserver/appclient/server/core/src/main/java/org/glassfish/appclient/server/core/jws/JavaWebStartInfo.java
index 53892b3..b7889f0 100644
--- a/appserver/appclient/server/core/src/main/java/org/glassfish/appclient/server/core/jws/JavaWebStartInfo.java
+++ b/appserver/appclient/server/core/src/main/java/org/glassfish/appclient/server/core/jws/JavaWebStartInfo.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022 Contributors to the Eclipse Foundation
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -18,7 +19,6 @@
 
 import com.sun.enterprise.deployment.ApplicationClientDescriptor;
 import com.sun.enterprise.universal.i18n.LocalStringsImpl;
-import com.sun.logging.LogDomains;
 import java.beans.PropertyChangeEvent;
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -133,8 +133,8 @@
 
     private String signingAlias;
 
-    final private Map<String,StaticContent> staticContent = new HashMap<String,StaticContent>();
-    final private Map<String,DynamicContent> dynamicContent = new HashMap<String,DynamicContent>();
+    final private Map<String,StaticContent> staticContent = new HashMap<>();
+    final private Map<String,DynamicContent> dynamicContent = new HashMap<>();
 
     private static final String JNLP_MIME_TYPE = "application/x-java-jnlp-file";
 
@@ -423,7 +423,7 @@
 
         dch.addDeveloperContentFromPath(developerJNLPDoc);
 
-        Set<Content> result = new HashSet<Content>(staticContent.values());
+        Set<Content> result = new HashSet<>(staticContent.values());
         result.addAll(dynamicContent.values());
 
         jwsAdapterManager.addContentForAppClient(
@@ -498,7 +498,7 @@
 
     private void addSignedSystemContent(
             ) throws FileNotFoundException, IOException {
-        final List<String> systemJARRelativeURIs = new ArrayList<String>();
+        final List<String> systemJARRelativeURIs = new ArrayList<>();
         final Map<String,StaticContent> addedStaticContent =
                 jwsAdapterManager.addStaticSystemContent(
                     systemJARRelativeURIs,
@@ -663,17 +663,12 @@
     public static File signedFileForProvidedAppFile(final URI relURI,
             final File unsignedFile,
             final AppClientDeployerHelper helper,
-            final DeploymentContext dc) {    /*
-         * Place a signed file for a developer-provided file at
-         *
-         * generated/xml/(appName)/signed/(path-within-app-of-unsigned-file)
-         *
-         *
-         */
+            final DeploymentContext dc) {
+         // Place a signed file for a developer-provided file at
+        // generated/xml/(appName)/signed/(path-within-app-of-unsigned-file)
         final File rootForSignedFilesInApp = helper.rootForSignedFilesInApp();
         mkdirs(rootForSignedFilesInApp);
         final URI signedFileURI = rootForSignedFilesInApp.toURI().resolve(relURI);
-
         return new File(signedFileURI);
     }
 
@@ -805,7 +800,7 @@
     }
 
     public static class VendorInfo {
-        private String vendorStringFromDescriptor;
+        private final String vendorStringFromDescriptor;
         private String vendor = "";
         private String imageURIString = "";
         private String splashImageURIString = "";
@@ -858,7 +853,7 @@
     @Override
     public UnprocessedChangeEvents changed(PropertyChangeEvent[] events) {
         /* Record any events we tried to process but could not. */
-        List<UnprocessedChangeEvent> unprocessedEvents = new ArrayList<UnprocessedChangeEvent>();
+        List<UnprocessedChangeEvent> unprocessedEvents = new ArrayList<>();
 
         for (PropertyChangeEvent event : events) {
             try {
diff --git a/appserver/appclient/server/core/src/main/java/org/glassfish/appclient/server/core/jws/servedcontent/ASJarSigner.java b/appserver/appclient/server/core/src/main/java/org/glassfish/appclient/server/core/jws/servedcontent/ASJarSigner.java
index 939cd7b..875ec8c 100644
--- a/appserver/appclient/server/core/src/main/java/org/glassfish/appclient/server/core/jws/servedcontent/ASJarSigner.java
+++ b/appserver/appclient/server/core/src/main/java/org/glassfish/appclient/server/core/jws/servedcontent/ASJarSigner.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022 Contributors to the Eclipse Foundation
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -18,34 +19,37 @@
 
 import com.sun.enterprise.server.pluggable.SecuritySupport;
 import com.sun.enterprise.util.i18n.StringManager;
-import com.sun.logging.LogDomains;
 
-import static java.util.Arrays.asList;
+import jakarta.inject.Singleton;
 
+import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
+import java.io.OutputStream;
 import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
 import java.security.PrivateKey;
+import java.security.UnrecoverableKeyException;
 import java.security.cert.CertPath;
 import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.Map;
 import java.util.jar.Attributes;
 import java.util.jar.JarFile;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import java.util.zip.ZipOutputStream;
 
-import org.jvnet.hk2.annotations.Service;
 import org.glassfish.hk2.api.PostConstruct;
-import jakarta.inject.Singleton;
-import jdk.security.jarsigner.JarSigner;
-import jdk.security.jarsigner.JarSignerException;
+import org.jvnet.hk2.annotations.Service;
 
-import org.glassfish.appclient.server.core.jws.JavaWebStartInfo;
+import jdk.security.jarsigner.JarSigner;
+
+import static java.util.Arrays.asList;
+import static org.glassfish.appclient.server.core.jws.JavaWebStartInfo.APPCLIENT_SERVER_LOGMESSAGE_RESOURCE;
+import static org.glassfish.appclient.server.core.jws.JavaWebStartInfo.APPCLIENT_SERVER_MAIN_LOGGER;
 
 /**
  * Signs a specified JAR file.
@@ -66,73 +70,53 @@
     /** property name optionally set by the admin in domain.xml to select an alias for signing */
     public static final String USER_SPECIFIED_ALIAS_PROPERTYNAME = "com.sun.aas.jws.signing.alias";
 
-    /** keystore type for JKS keystores */
-    private static final String JKS_KEYSTORE_TYPE_VALUE = "jks";
-
     /** default alias for signing if the admin does not specify one */
     private static final String DEFAULT_ALIAS_VALUE = "s1as";
 
-    private static final String DEFAULT_DIGEST_ALGORITHM = "SHA-1";
-    private static final String DEFAULT_SIGNATURE_ALGORITHM = "SHA1withRSA";
+    private static final String DEFAULT_DIGEST_ALGORITHM = "SHA-256";
+    private static final String DEFAULT_SIGNATURE_ALGORITHM = "SHA256withRSA";
 
     private static final SecuritySupport securitySupport = SecuritySupport.getDefaultInstance();
 
-//    /** user-specified signing alias */
-//    private final String userAlias; // = System.getProperty(USER_SPECIFIED_ALIAS_PROPERTYNAME);
-
     private static final StringManager localStrings = StringManager.getManager(ASJarSigner.class);
 
     private Logger logger;
 
     @Override
     public void postConstruct() {
-        logger =Logger.getLogger(JavaWebStartInfo.APPCLIENT_SERVER_MAIN_LOGGER, JavaWebStartInfo.APPCLIENT_SERVER_LOGMESSAGE_RESOURCE);
+        logger = Logger.getLogger(APPCLIENT_SERVER_MAIN_LOGGER, APPCLIENT_SERVER_LOGMESSAGE_RESOURCE);
     }
 
-    /**
-     *Creates a signed jar from the specified unsigned jar.
-     *@param unsignedJar the unsigned JAR file
-     *@param signedJar the signed JAR to be created
-     *@param attrs additional attributes to be added to the JAR's manifest main section
-     *@return the elapsed time to sign the JAR (in milliseconds)
-     *@throws Exception getting the keystores from SSLUtils fails
-     */
-    public long signJar(final File unsignedJar, final File signedJar,
-        String alias, Attributes attrs) throws Exception {
 
-        final ZipOutputStream zout = new ZipOutputStream(
-                    new FileOutputStream(signedJar));
-        try {
-            final long result = signJar(unsignedJar, zout, alias, attrs, Collections.EMPTY_MAP);
-            return result;
-        } catch (Exception ex) {
-            /*
-             *In case of any problems, make sure there is no ill-formed signed
-             *jar file left behind.
-             */
-            if ( signedJar.exists() && ! signedJar.delete()) {
-                logger.log(Level.FINE, "Could not remove generated signed JAR {0} after JarSigner reported an error",
-                       signedJar.getAbsolutePath());
-            }
-            throw ex;
-        } finally {
-            zout.close();
+    /**
+     * Creates a signed jar from the specified unsigned jar.
+     *
+     * @param unsignedJar the unsigned JAR file
+     * @param signedJar the signed JAR to be created
+     * @param attrs additional attributes to be added to the JAR's manifest main section
+     * @return the elapsed time to sign the JAR (in milliseconds)
+     * @throws Exception getting the keystores from SSLUtils fails
+     */
+    public long signJar(final File unsignedJar, final File signedJar, String alias, Attributes attrs) throws Exception {
+        try (OutputStream zout = new BufferedOutputStream(new FileOutputStream(signedJar))) {
+            return signJar(unsignedJar, zout, alias, attrs, Collections.emptyMap());
         }
     }
 
+
     /**
      * Creates a signed ZIP output stream from an unsigned JAR and, possibly, additional content.
+     *
      * @param unsignedJar JAR file containing most of the content to sign and return
      * @param signedJar already-opened ZipOutputStream to receive the signed content
      * @param alias the alias with which to identify the cert for signing the output
      * @param attrs additional manifest attributes to add
      * @param additionalContent additional JAR entries to add
-     * @return
-     * @throws Exception
+     * @return the elapsed time to sign the JAR (in milliseconds)
+     * @throws IllegalStateException
      */
-    public long signJar(final File unsignedJar, final ZipOutputStream signedJar,
-            String alias, final Attributes attrs, final Map<String,byte[]> additionalContent) throws Exception {
-
+    public long signJar(final File unsignedJar, final OutputStream signedJar, String alias, final Attributes attrs,
+        final Map<String, byte[]> additionalContent) throws IllegalStateException {
         if (alias == null) {
             alias = DEFAULT_ALIAS_VALUE;
         }
@@ -140,48 +124,56 @@
         long duration = 0;
         synchronized(this) {
             try {
-                Certificate[] certificates = null;
-                PrivateKey privateKey = null;
-                KeyStore[] keyStores = securitySupport.getKeyStores();
-                for (int i = 0; i < keyStores.length; i++) {
-                    privateKey = securitySupport.getPrivateKeyForAlias(alias, i);
-                    if (privateKey != null) {
-                        certificates = keyStores[i].getCertificateChain(alias);
-                    }
-                }
-
-                CertPath certPath = CertificateFactory.getInstance("X.509").generateCertPath(asList(certificates));
-
-                JarSigner signer = new JarSigner.Builder(privateKey, certPath)
-                        .digestAlgorithm(DEFAULT_DIGEST_ALGORITHM)
-                        .signatureAlgorithm(DEFAULT_SIGNATURE_ALGORITHM)
-                        .build();
-
+                JarSigner signer = createJarSigner(alias);
                 // TODO: add Attributes to Manifest and additionalContent
-
-                signer.sign(new JarFile(unsignedJar), signedJar);
-
-            } catch (Throwable t) {
-                /*
-                 *The jar signer will have written some information to System.out
-                 */
-                throw new Exception(localStrings.getString("jws.sign.errorSigning",
-                        unsignedJar.getAbsolutePath(), alias), t);
+                try (JarFile jarFile = new JarFile(unsignedJar)) {
+                    signer.sign(jarFile, signedJar);
+                }
+            } catch (Exception e) {
+                throw new IllegalStateException(
+                    localStrings.getString("jws.sign.errorSigning", unsignedJar.getAbsolutePath(), alias), e);
             } finally {
                 duration = System.currentTimeMillis() - startTime;
                 logger.log(Level.FINE, "Signing {0} took {1} ms",
-                        new Object[]{unsignedJar.getAbsolutePath(), duration});
+                    new Object[] {unsignedJar.getAbsolutePath(), duration});
             }
         }
         return duration;
     }
 
+
+    private JarSigner createJarSigner(final String alias)
+        throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException, CertificateException {
+        Certificate[] certificates = null;
+        PrivateKey privateKey = null;
+        KeyStore[] keyStores = securitySupport.getKeyStores();
+        for (int i = 0; i < keyStores.length; i++) {
+            privateKey = securitySupport.getPrivateKeyForAlias(alias, i);
+            if (privateKey == null) {
+                continue;
+            }
+            certificates = keyStores[i].getCertificateChain(alias);
+            if (certificates != null && certificates.length > 0) {
+                break;
+            }
+        }
+        if (certificates == null) {
+            throw new IllegalStateException("No certificates available for the alias: " + alias);
+        }
+        CertPath certPath = CertificateFactory.getInstance("X.509").generateCertPath(asList(certificates));
+        return new JarSigner.Builder(privateKey, certPath)
+                .digestAlgorithm(DEFAULT_DIGEST_ALGORITHM)
+                .signatureAlgorithm(DEFAULT_SIGNATURE_ALGORITHM)
+                .build();
+    }
+
+
     /**
-     *Wraps any underlying exception.
-     *<p>
-     *This is primarily used to insulate calling logic from
-     *the large variety of exceptions that can occur during signing
-     *from which the caller cannot really recover.
+     * Wraps any underlying exception.
+     * <p>
+     * This is primarily used to insulate calling logic from
+     * the large variety of exceptions that can occur during signing
+     * from which the caller cannot really recover.
      */
     public static class ASJarSignerException extends Exception {
         public ASJarSignerException(String msg, Throwable t) {
diff --git a/appserver/appclient/server/core/src/main/java/org/glassfish/appclient/server/core/jws/servedcontent/AutoSignedContent.java b/appserver/appclient/server/core/src/main/java/org/glassfish/appclient/server/core/jws/servedcontent/AutoSignedContent.java
index 19c22c2..73d6990 100644
--- a/appserver/appclient/server/core/src/main/java/org/glassfish/appclient/server/core/jws/servedcontent/AutoSignedContent.java
+++ b/appserver/appclient/server/core/src/main/java/org/glassfish/appclient/server/core/jws/servedcontent/AutoSignedContent.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022 Contributors to the Eclipse Foundation
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,17 +17,15 @@
 
 package org.glassfish.appclient.server.core.jws.servedcontent;
 
-import com.sun.enterprise.util.net.NetUtils;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.nio.file.Files;
 import java.text.MessageFormat;
 import java.util.ResourceBundle;
 import java.util.jar.Attributes;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 
 /**
  * Represents otherwise fixed content that must be automatically signed
@@ -64,7 +63,6 @@
     private final File signedFile;
     private final String userProvidedAlias;
     private final ASJarSigner jarSigner;
-    private final URI relativeURI;
     private final String appName;
 
     public AutoSignedContent(final File unsignedFile,
@@ -80,7 +78,6 @@
         this.signedFile = signedFile;
         this.userProvidedAlias = userProvidedAlias;
         this.jarSigner = jarSigner;
-        this.relativeURI = URI.create(relativeURI);
         this.appName = appName;
     }
 
@@ -151,7 +148,15 @@
             }
         }
         final Attributes attrs = createJWSAttrs(requestURI, appName);
-        jarSigner.signJar(unsignedFile, signedFile, userProvidedAlias, attrs);
+        try {
+            jarSigner.signJar(unsignedFile, signedFile, userProvidedAlias, attrs);
+        } catch (Exception e) {
+            // File may be already created, but probably has corrupted content.
+            if (signedFile.exists()) {
+                Files.deleteIfExists(signedFile.toPath());
+            }
+            throw e;
+        }
     }
 
     @Override
diff --git a/appserver/appclient/server/core/src/main/java/org/glassfish/appclient/server/core/jws/servedcontent/StreamedAutoSignedStaticContent.java b/appserver/appclient/server/core/src/main/java/org/glassfish/appclient/server/core/jws/servedcontent/StreamedAutoSignedStaticContent.java
index 79d8cfe..f9bb224 100644
--- a/appserver/appclient/server/core/src/main/java/org/glassfish/appclient/server/core/jws/servedcontent/StreamedAutoSignedStaticContent.java
+++ b/appserver/appclient/server/core/src/main/java/org/glassfish/appclient/server/core/jws/servedcontent/StreamedAutoSignedStaticContent.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022 Contributors to the Eclipse Foundation
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -22,6 +23,7 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.net.URI;
+import java.net.URISyntaxException;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.logging.Level;
@@ -105,35 +107,26 @@
          * Instead we'll just write to the output stream and Grizzly will
          * chunk it for us if needed.
          */
-        final ZipOutputStream zos = new ZipOutputStream(gResp.getOutputStream());
 
         logger.log(Level.FINE, "Request's session contains cached JNLP");
         final byte[] jnlpContent = (byte[]) jwsObj;
-        final Map<String,byte[]> addedContent = new HashMap<String,byte[]>();
+        final Map<String,byte[]> addedContent = new HashMap<>();
         addedContent.put(SIGNED_JNLP_PATH, jnlpContent);
         try {
-            jarSigner().signJar(unsignedFile(), zos, userProvidedAlias(), createJWSAttrs(AppClientHTTPAdapter.requestURI(gReq), appName()), addedContent);
-            /*
-             * Create an on-disk copy of the signed JAR for debugging purposes
-             * if logging is detailed enough.
-             */
+            jarSigner().signJar(unsignedFile(), gResp.getOutputStream(), userProvidedAlias(),
+                createJWSAttrs(AppClientHTTPAdapter.requestURI(gReq), appName()), addedContent);
+             // Create an on-disk copy of the signed JAR for debugging purposes if logging is detailed enough.
             if (logger.isLoggable(Level.FINEST)) {
-                final File debugSignedJARFile = new File(unsignedFile().getAbsolutePath()+".debug");
-                final ZipOutputStream dbgZos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(debugSignedJARFile)));
-                try {
-                    jarSigner().signJar(unsignedFile(), dbgZos, userProvidedAlias(), createJWSAttrs(AppClientHTTPAdapter.requestURI(gReq), appName()), addedContent);
-                } finally {
-                    dbgZos.close();
+                final File debugSignedJARFile = new File(unsignedFile().getAbsolutePath() + ".debug");
+                try (ZipOutputStream dbgZos = new ZipOutputStream(
+                    new BufferedOutputStream(new FileOutputStream(debugSignedJARFile)))) {
+                    jarSigner().signJar(unsignedFile(), dbgZos, userProvidedAlias(),
+                        createJWSAttrs(AppClientHTTPAdapter.requestURI(gReq), appName()), addedContent);
                 }
                 logger.log(Level.FINEST, "Created on-disk signed JAR {0}", debugSignedJARFile.getAbsolutePath());
             }
-            zos.close();
-        } catch (IOException ioex) {
-            throw ioex;
-        } catch (Exception ex) {
+        } catch (URISyntaxException ex) {
             throw new IOException(ex);
-        } finally {
-            zos.close();
         }
     }
 
@@ -156,10 +149,8 @@
 
         if (dot > 0) {
             String ext = substr.substring(dot + 1);
-            String ct = MimeType.get(ext);
-            return ct;
-        } else {
-            return MimeType.get("html");
+            return MimeType.get(ext);
         }
+        return MimeType.get("html");
     }
 }
diff --git a/appserver/appclient/server/core/src/main/resources/org/glassfish/appclient/server/core/jws/servedcontent/LocalStrings.properties b/appserver/appclient/server/core/src/main/resources/org/glassfish/appclient/server/core/jws/servedcontent/LocalStrings.properties
index a9855f5..9309300 100644
--- a/appserver/appclient/server/core/src/main/resources/org/glassfish/appclient/server/core/jws/servedcontent/LocalStrings.properties
+++ b/appserver/appclient/server/core/src/main/resources/org/glassfish/appclient/server/core/jws/servedcontent/LocalStrings.properties
@@ -22,7 +22,7 @@
 jws.sign.userAliasAbsent=User-specified alias {0} to be used for signing JAR files was not found in any keystore; attempting to use default alias instead
 jws.sign.aliasNotFound=Alias {0} not found in keystore(s); aborting
 jws.sign.aliasFoundMult=Alias {0} to be used for signing JAR files was found in more than one keystore; using the first occurrence from the keystores with these providers: {1}
-jws.sign.errorSigning=Error attempting to create signed jar {0} with alias {1}
+jws.sign.errorSigning=Error attempting to sign jar {0} with alias {1}
 jws.sign.errorCreatingDir=Unknown error attempting to create directory {0} to contain signed jar
 jws.sign.keyNotPrivate=Key for alias {0} is not a private key, as required
 jws.sign.notX509Cert=Certificate associated with alias {0} is not an X509 certificate, as required
diff --git a/appserver/security/appclient.security/src/main/java/com/sun/enterprise/security/appclient/ConfigXMLParser.java b/appserver/security/appclient.security/src/main/java/com/sun/enterprise/security/appclient/ConfigXMLParser.java
index 8e0aa43..955b1f0 100644
--- a/appserver/security/appclient.security/src/main/java/com/sun/enterprise/security/appclient/ConfigXMLParser.java
+++ b/appserver/security/appclient.security/src/main/java/com/sun/enterprise/security/appclient/ConfigXMLParser.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022 Contributors to the Eclipse Foundation
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -18,6 +19,7 @@
 
 import static java.util.regex.Matcher.quoteReplacement;
 
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -59,8 +61,8 @@
     private static Pattern PROPERTY_PATTERN = Pattern.compile("\\$\\{\\{(.*?)}}|\\$\\{(.*?)}");
 
     // configuration info
-    private Map configMap = new HashMap();
-    private Set<String> layersWithDefault = new HashSet<String>();
+    private final Map configMap = new HashMap();
+    private final Set<String> layersWithDefault = new HashSet<>();
     private List<MessageSecurityConfig> msgSecConfigs = null;
     private static final String ACC_XML = "glassfish-acc.xml.url";
 
@@ -90,10 +92,12 @@
 
     }
 
+    @Override
     public Map getConfigMap() {
         return configMap;
     }
 
+    @Override
     public Set<String> getLayersWithDefault() {
         return layersWithDefault;
     }
@@ -218,23 +222,18 @@
         return AuthMessagePolicy.getMessagePolicy(authSource, authRecipient);
     }
 
+    @Override
     public void initialize(Object config) throws IOException {
         String sun_acc = System.getProperty(ACC_XML, "glassfish-acc.xml");
         List<MessageSecurityConfig> msgconfigs = null;
-        if (Globals.getDefaultHabitat() == null && sun_acc != null) {
-            InputStream is = null;
-            try {
-                is = new FileInputStream(sun_acc);
+        if (Globals.getDefaultHabitat() == null && sun_acc != null && new File(sun_acc).exists()) {
+            try (InputStream is = new FileInputStream(sun_acc)) {
                 JAXBContext jc = JAXBContext.newInstance(ClientContainer.class);
                 Unmarshaller u = jc.createUnmarshaller();
                 ClientContainer cc = (ClientContainer) u.unmarshal(is);
                 msgconfigs = cc.getMessageSecurityConfig();
             } catch (JAXBException ex) {
                 _logger.log(Level.SEVERE, null, ex);
-            } finally {
-                if (is != null) {
-                    is.close();
-                }
             }
         } else {
             Util util = Util.getInstance();