Explorar el Código

maven updated and minor fixes

Jason Rivard hace 2 años
padre
commit
adb5fec19f
Se han modificado 28 ficheros con 239 adiciones y 420 borrados
  1. 3 4
      README.md
  2. 2 2
      data-service/pom.xml
  3. 2 2
      docker/pom.xml
  4. 8 8
      pom.xml
  5. 5 5
      server/pom.xml
  6. 0 1
      server/src/main/java/password/pwm/AppProperty.java
  7. 14 65
      server/src/main/java/password/pwm/PwmApplication.java
  8. 53 0
      server/src/main/java/password/pwm/PwmApplicationUtil.java
  9. 5 0
      server/src/main/java/password/pwm/http/ContextManager.java
  10. 2 2
      server/src/main/java/password/pwm/http/servlet/configeditor/ConfigEditorServlet.java
  11. 1 1
      server/src/main/java/password/pwm/http/servlet/setupresponses/SetupResponsesServlet.java
  12. 2 2
      server/src/main/java/password/pwm/svc/AbstractPwmService.java
  13. 0 11
      server/src/main/java/password/pwm/svc/db/DBConfiguration.java
  14. 1 1
      server/src/main/java/password/pwm/svc/db/DatabaseAccessorImpl.java
  15. 3 24
      server/src/main/java/password/pwm/svc/db/DatabaseService.java
  16. 98 234
      server/src/main/java/password/pwm/svc/db/JDBCDriverLoader.java
  17. 1 1
      server/src/main/java/password/pwm/svc/event/LocalDbAuditVault.java
  18. 10 4
      server/src/main/java/password/pwm/svc/userhistory/DatabaseUserHistory.java
  19. 8 7
      server/src/main/java/password/pwm/svc/userhistory/LdapXmlUserHistory.java
  20. 1 1
      server/src/main/java/password/pwm/svc/wordlist/AbstractWordlist.java
  21. 4 7
      server/src/main/java/password/pwm/util/PwmScheduler.java
  22. 7 7
      server/src/main/java/password/pwm/util/SampleDataGenerator.java
  23. 0 1
      server/src/main/resources/password/pwm/AppProperty.properties
  24. 2 1
      server/src/test/java/password/pwm/svc/event/LdapXmlUserHistoryTest.java
  25. 6 1
      server/src/test/java/password/pwm/util/macro/MacroTest.java
  26. 0 10
      webapp/pom.xml
  27. 0 17
      webapp/src/main/webapp/WEB-INF/jsp/admin-dashboard.jsp
  28. 1 1
      webapp/src/main/webapp/public/resources/js/main.js

+ 3 - 4
README.md

@@ -144,8 +144,7 @@ log, and runtime files.  Once PWM is configured, the initial web UI will prompt
 
 
 ### Java Executable
 ### Java Executable
 The 'onejar' artifact released with PWM has an embedded tomcat instance, so you don't need to install tomcat to use this
 The 'onejar' artifact released with PWM has an embedded tomcat instance, so you don't need to install tomcat to use this
-version.  You will be responsible for getting it to run as a service, and you won't be able to do any advanced tomcat
-configuration.  
+version.  It's ideal for testing and evaluating PWM.  You will be responsible for getting it to run as a service (if desired).  
 
 
 Requirements:
 Requirements:
 * Java 11 JDK or better
 * Java 11 JDK or better
@@ -158,7 +157,7 @@ Example for running onejar executable (with /pwm-applicationPath being the locat
 ```
 ```
 java -jar pwm-onejar-2.0.0.jar -applicationPath /pwm-applicationPath 
 java -jar pwm-onejar-2.0.0.jar -applicationPath /pwm-applicationPath 
 ```
 ```
-By default the executable will remain attached to the console and listen for HTTPS connections on port 8443.
+By default, the executable will remain attached to the console and listen for HTTPS connections on port 8443.
 
 
 
 
 ### WAR
 ### WAR
@@ -256,7 +255,7 @@ git clone https://github.com/pwm-project/pwm
 cd pwm
 cd pwm
 mvnw.cmd clean verify
 mvnw.cmd clean verify
 ```
 ```
-On Windows we recommend using paths without spaces (including for the JDK directory).
+On Windows we recommend using paths without spaces for both PWM and JDK directory.
 
 
 Artifacts created:
 Artifacts created:
 
 

+ 2 - 2
data-service/pom.xml

@@ -130,7 +130,7 @@
             <plugin>
             <plugin>
                 <groupId>com.google.cloud.tools</groupId>
                 <groupId>com.google.cloud.tools</groupId>
                 <artifactId>jib-maven-plugin</artifactId>
                 <artifactId>jib-maven-plugin</artifactId>
-                <version>3.3.1</version>
+                <version>3.3.2</version>
                 <executions>
                 <executions>
                     <execution>
                     <execution>
                         <id>make-docker-image</id>
                         <id>make-docker-image</id>
@@ -234,7 +234,7 @@
         <dependency>
         <dependency>
             <groupId>ch.qos.logback</groupId>
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-classic</artifactId>
             <artifactId>logback-classic</artifactId>
-            <version>1.4.6</version>
+            <version>1.4.7</version>
         </dependency>
         </dependency>
     </dependencies>
     </dependencies>
 </project>
 </project>

+ 2 - 2
docker/pom.xml

@@ -34,7 +34,7 @@
             <plugin>
             <plugin>
                 <groupId>com.google.cloud.tools</groupId>
                 <groupId>com.google.cloud.tools</groupId>
                 <artifactId>jib-maven-plugin</artifactId>
                 <artifactId>jib-maven-plugin</artifactId>
-                <version>3.3.1</version>
+                <version>3.3.2</version>
                 <executions>
                 <executions>
                     <execution>
                     <execution>
                         <id>make-docker-image</id>
                         <id>make-docker-image</id>
@@ -93,7 +93,7 @@
             <plugin>
             <plugin>
                 <groupId>org.codehaus.mojo</groupId>
                 <groupId>org.codehaus.mojo</groupId>
                 <artifactId>build-helper-maven-plugin</artifactId>
                 <artifactId>build-helper-maven-plugin</artifactId>
-                <version>3.3.0</version>
+                <version>3.4.0</version>
                 <executions>
                 <executions>
                     <execution>
                     <execution>
                         <id>attach-artifacts</id>
                         <id>attach-artifacts</id>

+ 8 - 8
pom.xml

@@ -180,7 +180,7 @@
             <plugin>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-enforcer-plugin</artifactId>
                 <artifactId>maven-enforcer-plugin</artifactId>
-                <version>3.2.1</version>
+                <version>3.3.0</version>
                 <executions>
                 <executions>
                     <execution>
                     <execution>
                         <id>enforce-maven</id>
                         <id>enforce-maven</id>
@@ -216,12 +216,12 @@
             <plugin>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
-                <version>3.2.1</version>
+                <version>3.2.2</version>
                 <dependencies>
                 <dependencies>
                     <dependency>
                     <dependency>
                         <groupId>com.puppycrawl.tools</groupId>
                         <groupId>com.puppycrawl.tools</groupId>
                         <artifactId>checkstyle</artifactId>
                         <artifactId>checkstyle</artifactId>
-                        <version>10.9.3</version>
+                        <version>10.11.0</version>
                     </dependency>
                     </dependency>
                 </dependencies>
                 </dependencies>
                 <executions>
                 <executions>
@@ -300,7 +300,7 @@
             <plugin>
             <plugin>
                 <groupId>com.github.spotbugs</groupId>
                 <groupId>com.github.spotbugs</groupId>
                 <artifactId>spotbugs-maven-plugin</artifactId>
                 <artifactId>spotbugs-maven-plugin</artifactId>
-                <version>4.7.3.3</version>
+                <version>4.7.3.4</version>
                 <dependencies>
                 <dependencies>
                     <dependency>
                     <dependency>
                         <groupId>com.github.spotbugs</groupId>
                         <groupId>com.github.spotbugs</groupId>
@@ -310,7 +310,7 @@
                 </dependencies>
                 </dependencies>
                 <configuration>
                 <configuration>
                     <skip>${spotbugs.skip}</skip>
                     <skip>${spotbugs.skip}</skip>
-                    <fork>false</fork>
+                    <fork>true</fork>
                     <excludeFilterFile>${project.root.basedir}/build/spotbugs-exclude.xml</excludeFilterFile>
                     <excludeFilterFile>${project.root.basedir}/build/spotbugs-exclude.xml</excludeFilterFile>
                     <includeTests>false</includeTests>
                     <includeTests>false</includeTests>
                     <effort>max</effort>
                     <effort>max</effort>
@@ -390,7 +390,7 @@
                 <plugin>
                 <plugin>
                     <groupId>org.apache.maven.plugins</groupId>
                     <groupId>org.apache.maven.plugins</groupId>
                     <artifactId>maven-surefire-plugin</artifactId>
                     <artifactId>maven-surefire-plugin</artifactId>
-                    <version>3.0.0</version>
+                    <version>3.1.0</version>
                     <executions>
                     <executions>
                         <execution>
                         <execution>
                             <id>default-test</id>
                             <id>default-test</id>
@@ -460,13 +460,13 @@
         <dependency>
         <dependency>
             <groupId>org.mockito</groupId>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-core</artifactId>
             <artifactId>mockito-core</artifactId>
-            <version>5.2.0</version>
+            <version>5.3.1</version>
             <scope>test</scope>
             <scope>test</scope>
         </dependency>
         </dependency>
         <dependency>
         <dependency>
             <groupId>com.github.tomakehurst</groupId>
             <groupId>com.github.tomakehurst</groupId>
             <artifactId>wiremock</artifactId>
             <artifactId>wiremock</artifactId>
-            <version>3.0.0-beta-6</version>
+            <version>3.0.0-beta-8</version>
             <scope>test</scope>
             <scope>test</scope>
         </dependency>
         </dependency>
         <dependency>
         <dependency>

+ 5 - 5
server/pom.xml

@@ -173,7 +173,7 @@
         <dependency>
         <dependency>
             <groupId>com.github.ldapchai</groupId>
             <groupId>com.github.ldapchai</groupId>
             <artifactId>ldapchai</artifactId>
             <artifactId>ldapchai</artifactId>
-            <version>0.8.4</version>
+            <version>0.8.5</version>
         </dependency>
         </dependency>
         <dependency>
         <dependency>
             <groupId>org.jrivard.xmlchai</groupId>
             <groupId>org.jrivard.xmlchai</groupId>
@@ -183,7 +183,7 @@
         <dependency>
         <dependency>
             <groupId>org.apache.directory.api</groupId>
             <groupId>org.apache.directory.api</groupId>
             <artifactId>api-all</artifactId>
             <artifactId>api-all</artifactId>
-            <version>2.1.2</version>
+            <version>2.1.3</version>
         </dependency>
         </dependency>
         <dependency>
         <dependency>
             <groupId>org.apache.commons</groupId>
             <groupId>org.apache.commons</groupId>
@@ -218,7 +218,7 @@
         <dependency>
         <dependency>
             <groupId>ch.qos.logback</groupId>
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-classic</artifactId>
             <artifactId>logback-classic</artifactId>
-            <version>1.4.6</version>
+            <version>1.4.7</version>
         </dependency>
         </dependency>
         <dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
             <groupId>org.slf4j</groupId>
@@ -259,7 +259,7 @@
         <dependency>
         <dependency>
             <groupId>com.squareup.moshi</groupId>
             <groupId>com.squareup.moshi</groupId>
             <artifactId>moshi</artifactId>
             <artifactId>moshi</artifactId>
-            <version>1.14.0</version>
+            <version>1.15.0</version>
         </dependency>
         </dependency>
         <dependency>
         <dependency>
             <groupId>com.blueconic</groupId>
             <groupId>com.blueconic</groupId>
@@ -280,7 +280,7 @@
         <dependency>
         <dependency>
             <groupId>com.github.ben-manes.caffeine</groupId>
             <groupId>com.github.ben-manes.caffeine</groupId>
             <artifactId>caffeine</artifactId>
             <artifactId>caffeine</artifactId>
-            <version>3.1.5</version>
+            <version>3.1.6</version>
         </dependency>
         </dependency>
         <dependency>
         <dependency>
             <groupId>com.nulab-inc</groupId>
             <groupId>com.nulab-inc</groupId>

+ 0 - 1
server/src/main/java/password/pwm/AppProperty.java

@@ -90,7 +90,6 @@ public enum AppProperty
     CLUSTER_LDAP_HEARTBEAT_SECONDS                  ( "cluster.ldap.heartbeatSeconds" ),
     CLUSTER_LDAP_HEARTBEAT_SECONDS                  ( "cluster.ldap.heartbeatSeconds" ),
     CLUSTER_LDAP_NODE_TIMEOUT_SECONDS               ( "cluster.ldap.nodeTimeoutSeconds" ),
     CLUSTER_LDAP_NODE_TIMEOUT_SECONDS               ( "cluster.ldap.nodeTimeoutSeconds" ),
     CLUSTER_LDAP_NODE_PURGE_SECONDS                 ( "cluster.ldap.nodePurgeSeconds" ),
     CLUSTER_LDAP_NODE_PURGE_SECONDS                 ( "cluster.ldap.nodePurgeSeconds" ),
-    DB_JDBC_LOAD_STRATEGY                           ( "db.jdbcLoadStrategy" ),
     DB_CONNECTIONS_MAX                              ( "db.connections.max" ),
     DB_CONNECTIONS_MAX                              ( "db.connections.max" ),
     DB_CONNECTIONS_TIMEOUT_MS                       ( "db.connections.timeoutMs" ),
     DB_CONNECTIONS_TIMEOUT_MS                       ( "db.connections.timeoutMs" ),
     DB_CONNECTIONS_WATCHDOG_FREQUENCY_SECONDS       ( "db.connections.watchdogFrequencySeconds" ),
     DB_CONNECTIONS_WATCHDOG_FREQUENCY_SECONDS       ( "db.connections.watchdogFrequencySeconds" ),

+ 14 - 65
server/src/main/java/password/pwm/PwmApplication.java

@@ -20,7 +20,6 @@
 
 
 package password.pwm;
 package password.pwm;
 
 
-import lombok.Value;
 import password.pwm.bean.DomainID;
 import password.pwm.bean.DomainID;
 import password.pwm.bean.ProfileID;
 import password.pwm.bean.ProfileID;
 import password.pwm.bean.SessionLabel;
 import password.pwm.bean.SessionLabel;
@@ -28,7 +27,6 @@ import password.pwm.config.AppConfig;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSettingScope;
 import password.pwm.config.PwmSettingScope;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.ErrorInformation;
-import password.pwm.error.PwmError;
 import password.pwm.error.PwmException;
 import password.pwm.error.PwmException;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.health.HealthService;
 import password.pwm.health.HealthService;
@@ -58,7 +56,7 @@ import password.pwm.svc.wordlist.SharedHistoryService;
 import password.pwm.svc.wordlist.WordlistService;
 import password.pwm.svc.wordlist.WordlistService;
 import password.pwm.util.MBeanUtility;
 import password.pwm.util.MBeanUtility;
 import password.pwm.util.PwmScheduler;
 import password.pwm.util.PwmScheduler;
-import password.pwm.util.java.FileSystemUtility;
+import password.pwm.util.java.CollectionUtil;
 import password.pwm.util.java.StringUtil;
 import password.pwm.util.java.StringUtil;
 import password.pwm.util.java.TimeDuration;
 import password.pwm.util.java.TimeDuration;
 import password.pwm.util.json.JsonFactory;
 import password.pwm.util.json.JsonFactory;
@@ -67,8 +65,6 @@ import password.pwm.util.logging.LocalDBLogger;
 import password.pwm.util.logging.PwmLogManager;
 import password.pwm.util.logging.PwmLogManager;
 import password.pwm.util.logging.PwmLogger;
 import password.pwm.util.logging.PwmLogger;
 
 
-import java.io.IOException;
-import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Path;
 import java.time.Instant;
 import java.time.Instant;
 import java.util.ArrayList;
 import java.util.ArrayList;
@@ -108,6 +104,7 @@ public class PwmApplication
     private String instanceID = PwmApplicationUtil.DEFAULT_INSTANCE_ID;
     private String instanceID = PwmApplicationUtil.DEFAULT_INSTANCE_ID;
     private LocalDB localDB;
     private LocalDB localDB;
     private LocalDBLogger localDBLogger;
     private LocalDBLogger localDBLogger;
+    private Path tempDirectory;
 
 
     public PwmApplication( final PwmEnvironment pwmEnvironment )
     public PwmApplication( final PwmEnvironment pwmEnvironment )
             throws PwmUnrecoverableException
             throws PwmUnrecoverableException
@@ -156,22 +153,8 @@ public class PwmApplication
             fileLocker.waitForFileLock();
             fileLocker.waitForFileLock();
         }
         }
 
 
-        // clear temp dir
-        if ( !pwmEnvironment.isInternalRuntimeInstance() )
-        {
-            final Path tempFileDirectory = getTempDirectory();
-            try
-            {
-                LOGGER.debug( sessionLabel, () -> "deleting directory (and sub-directory) contents in " + tempFileDirectory );
-                FileSystemUtility.deleteDirectoryContentsRecursively( tempFileDirectory );
-            }
-            catch ( final Exception e )
-            {
-                throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_STARTUP_ERROR,
-                        "unable to clear temp file directory '" + tempFileDirectory + "', error: " + e.getMessage()
-                ) );
-            }
-        }
+        // init temp dir
+        tempDirectory = PwmApplicationUtil.initTempDirectory( sessionLabel, pwmEnvironment );
 
 
         if ( getApplicationMode() != PwmApplicationMode.READ_ONLY )
         if ( getApplicationMode() != PwmApplicationMode.READ_ONLY )
         {
         {
@@ -509,7 +492,7 @@ public class PwmApplication
 
 
     public Map<ProfileID, ErrorInformation> readLastLdapFailure( final DomainID domainID )
     public Map<ProfileID, ErrorInformation> readLastLdapFailure( final DomainID domainID )
     {
     {
-        return readLastLdapFailure().getRecords().getOrDefault( domainID, Collections.emptyMap() );
+        return readLastLdapFailure().records().getOrDefault( domainID, Collections.emptyMap() );
     }
     }
 
 
     private StoredErrorRecords readLastLdapFailure()
     private StoredErrorRecords readLastLdapFailure()
@@ -534,34 +517,27 @@ public class PwmApplication
         return new StoredErrorRecords( Collections.emptyMap() );
         return new StoredErrorRecords( Collections.emptyMap() );
     }
     }
 
 
-    @Value
-    private static class StoredErrorRecords
+    private record StoredErrorRecords(
+            Map<DomainID, Map<ProfileID, ErrorInformation>> records
+    )
     {
     {
-        private final Map<DomainID, Map<ProfileID, ErrorInformation>> records;
-
-        StoredErrorRecords( final Map<DomainID, Map<ProfileID, ErrorInformation>> records )
-        {
-            this.records = records == null ? Collections.emptyMap() : Map.copyOf( records );
-        }
-
-        public Map<DomainID, Map<ProfileID, ErrorInformation>> getRecords()
+        private StoredErrorRecords( final Map<DomainID, Map<ProfileID, ErrorInformation>> records )
         {
         {
-            // required because json deserialization can still set records == null
-            return records == null ? Collections.emptyMap() : records;
+            this.records = CollectionUtil.stripNulls( records );
         }
         }
 
 
         StoredErrorRecords addDomainErrorMap(
         StoredErrorRecords addDomainErrorMap(
                 final DomainID domainID,
                 final DomainID domainID,
                 final Map<ProfileID, ErrorInformation> errorInformationMap )
                 final Map<ProfileID, ErrorInformation> errorInformationMap )
         {
         {
-            final Map<DomainID, Map<ProfileID, ErrorInformation>> newRecords = new HashMap<>( getRecords() );
+            final Map<DomainID, Map<ProfileID, ErrorInformation>> newRecords = new HashMap<>( records );
             newRecords.put( domainID, Map.copyOf( errorInformationMap ) );
             newRecords.put( domainID, Map.copyOf( errorInformationMap ) );
             return new StoredErrorRecords( newRecords );
             return new StoredErrorRecords( newRecords );
         }
         }
 
 
         StoredErrorRecords stripOutdatedLdapErrors( final TimeDuration maxAge )
         StoredErrorRecords stripOutdatedLdapErrors( final TimeDuration maxAge )
         {
         {
-            return new StoredErrorRecords( getRecords().entrySet().stream()
+            return new StoredErrorRecords( records.entrySet().stream()
                     // outer map
                     // outer map
                     .collect( Collectors.toUnmodifiableMap(
                     .collect( Collectors.toUnmodifiableMap(
                             Map.Entry::getKey,
                             Map.Entry::getKey,
@@ -787,39 +763,12 @@ public class PwmApplication
         return this.getConfig().isMultiDomain();
         return this.getConfig().isMultiDomain();
     }
     }
 
 
-    public Path getTempDirectory( )
+    public Optional<Path> getTempDirectory( )
             throws PwmUnrecoverableException
             throws PwmUnrecoverableException
     {
     {
-        if ( pwmEnvironment.getApplicationPath() == null )
-        {
-            final ErrorInformation errorInformation = new ErrorInformation(
-                    PwmError.ERROR_STARTUP_ERROR,
-                    "unable to establish temp work directory: application path unavailable"
-            );
-            throw new PwmUnrecoverableException( errorInformation );
-        }
-        final Path tempDirectory = pwmEnvironment.getApplicationPath().resolve( "temp" );
-        if ( !Files.exists( tempDirectory ) )
-        {
-            LOGGER.trace( () -> "preparing to create temporary directory " + tempDirectory );
-            try
-            {
-                Files.createDirectories( tempDirectory );
-                LOGGER.debug( () -> "created " + tempDirectory );
-            }
-            catch ( final IOException e )
-            {
-                LOGGER.debug( () -> "unable to create temporary directory " + tempDirectory );
-                final ErrorInformation errorInformation = new ErrorInformation(
-                        PwmError.ERROR_STARTUP_ERROR,
-                        "unable to establish create temp work directory " + tempDirectory );
-                throw new PwmUnrecoverableException( errorInformation );
-            }
-        }
-        return tempDirectory;
+        return Optional.ofNullable( tempDirectory );
     }
     }
 
 
-
     public PwmScheduler getPwmScheduler()
     public PwmScheduler getPwmScheduler()
     {
     {
         return pwmScheduler;
         return pwmScheduler;

+ 53 - 0
server/src/main/java/password/pwm/PwmApplicationUtil.java

@@ -21,6 +21,7 @@
 package password.pwm;
 package password.pwm;
 
 
 import password.pwm.bean.DomainID;
 import password.pwm.bean.DomainID;
+import password.pwm.bean.SessionLabel;
 import password.pwm.config.stored.StoredConfigKey;
 import password.pwm.config.stored.StoredConfigKey;
 import password.pwm.config.stored.StoredConfiguration;
 import password.pwm.config.stored.StoredConfiguration;
 import password.pwm.config.stored.StoredConfigurationUtil;
 import password.pwm.config.stored.StoredConfigurationUtil;
@@ -45,6 +46,7 @@ import password.pwm.util.secure.PwmRandom;
 import password.pwm.util.secure.X509Utils;
 import password.pwm.util.secure.X509Utils;
 
 
 import java.io.ByteArrayOutputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.OutputStream;
 import java.nio.file.Files;
 import java.nio.file.Files;
@@ -354,4 +356,55 @@ class PwmApplicationUtil
     {
     {
         return PwmRandom.getInstance().randomUUID().toString();
         return PwmRandom.getInstance().randomUUID().toString();
     }
     }
+
+    static Path initTempDirectory( final SessionLabel sessionLabel, final PwmEnvironment pwmEnvironment )
+            throws PwmUnrecoverableException
+    {
+        if ( pwmEnvironment.getApplicationPath() == null )
+        {
+            final ErrorInformation errorInformation = new ErrorInformation(
+                    PwmError.ERROR_STARTUP_ERROR,
+                    "unable to establish temp work directory: application path unavailable"
+            );
+            throw new PwmUnrecoverableException( errorInformation );
+        }
+
+        final Path tempDirectory = pwmEnvironment.getApplicationPath().resolve( "temp" );
+
+        if ( !Files.exists( tempDirectory ) )
+        {
+            LOGGER.trace( sessionLabel, () -> "preparing to create temporary directory " + tempDirectory );
+            try
+            {
+                Files.createDirectories( tempDirectory );
+                LOGGER.debug( sessionLabel, () -> "created " + tempDirectory );
+            }
+            catch ( final IOException e )
+            {
+                LOGGER.debug( sessionLabel, () -> "unable to create temporary directory " + tempDirectory );
+                final ErrorInformation errorInformation = new ErrorInformation(
+                        PwmError.ERROR_STARTUP_ERROR,
+                        "unable to establish create temp work directory " + tempDirectory );
+                throw new PwmUnrecoverableException( errorInformation );
+            }
+        }
+
+        // clear temp dir
+        if ( !pwmEnvironment.isInternalRuntimeInstance() )
+        {
+            try
+            {
+                LOGGER.debug( sessionLabel, () -> "deleting directory (and sub-directory) contents in " + tempDirectory );
+                FileSystemUtility.deleteDirectoryContentsRecursively( tempDirectory );
+            }
+            catch ( final Exception e )
+            {
+                throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_STARTUP_ERROR,
+                        "unable to clear temp file directory '" + tempDirectory + "', error: " + e.getMessage()
+                ) );
+            }
+        }
+
+        return tempDirectory;
+    }
 }
 }

+ 5 - 0
server/src/main/java/password/pwm/http/ContextManager.java

@@ -257,6 +257,11 @@ public class ContextManager
             handleStartupError( "unable to initialize application: ", e );
             handleStartupError( "unable to initialize application: ", e );
         }
         }
 
 
+        if ( taskMaster != null )
+        {
+            taskMaster.shutdownNow();
+        }
+
         taskMaster = Executors.newSingleThreadScheduledExecutor(
         taskMaster = Executors.newSingleThreadScheduledExecutor(
                 PwmScheduler.makePwmThreadFactory(
                 PwmScheduler.makePwmThreadFactory(
                         PwmScheduler.makeThreadName( SESSION_LABEL, pwmApplication, this.getClass() ) + "-"
                         PwmScheduler.makeThreadName( SESSION_LABEL, pwmApplication, this.getClass() ) + "-"

+ 2 - 2
server/src/main/java/password/pwm/http/servlet/configeditor/ConfigEditorServlet.java

@@ -672,7 +672,7 @@ public class ConfigEditorServlet extends ControlledPwmServlet
             final Optional<EmailServer> emailServer = EmailServerUtil.makeEmailServer( testDomainConfig, emailServerProfile, null );
             final Optional<EmailServer> emailServer = EmailServerUtil.makeEmailServer( testDomainConfig, emailServerProfile, null );
             if ( emailServer.isPresent() )
             if ( emailServer.isPresent() )
             {
             {
-                final MacroRequest macroRequest = SampleDataGenerator.sampleMacroRequest( pwmRequest.getPwmDomain() );
+                final MacroRequest macroRequest = SampleDataGenerator.sampleMacroRequest( pwmRequest.getPwmApplication().getTempDirectory().orElseThrow() );
 
 
                 try
                 try
                 {
                 {
@@ -800,7 +800,7 @@ public class ConfigEditorServlet extends ControlledPwmServlet
                 return ProcessStatus.Halt;
                 return ProcessStatus.Halt;
             }
             }
 
 
-            final MacroRequest macroRequest = SampleDataGenerator.sampleMacroRequest( pwmRequest.getPwmDomain() );
+            final MacroRequest macroRequest = SampleDataGenerator.sampleMacroRequest( pwmRequest.getPwmApplication().getTempDirectory().orElseThrow() );
             final String input = inputMap.get( "input" );
             final String input = inputMap.get( "input" );
             final String output = macroRequest.expandMacros( input );
             final String output = macroRequest.expandMacros( input );
             pwmRequest.outputJsonResult( RestResultBean.withData( output, String.class ) );
             pwmRequest.outputJsonResult( RestResultBean.withData( output, String.class ) );

+ 1 - 1
server/src/main/java/password/pwm/http/servlet/setupresponses/SetupResponsesServlet.java

@@ -301,7 +301,7 @@ public class SetupResponsesServlet extends ControlledPwmServlet
 
 
             final Instant startMakeResponseSet = Instant.now();
             final Instant startMakeResponseSet = Instant.now();
             SetupResponsesUtil.generateResponseInfoBean( pwmRequest, challengeSet, responseMap, Collections.emptyMap() );
             SetupResponsesUtil.generateResponseInfoBean( pwmRequest, challengeSet, responseMap, Collections.emptyMap() );
-            LOGGER.error( pwmRequest, () -> "generated hashed response set in "
+            LOGGER.trace( pwmRequest, () -> "generated hashed response set in "
                     + TimeDuration.fromCurrent( startMakeResponseSet ).asCompactString() );
                     + TimeDuration.fromCurrent( startMakeResponseSet ).asCompactString() );
             success = true;
             success = true;
         }
         }

+ 2 - 2
server/src/main/java/password/pwm/svc/AbstractPwmService.java

@@ -174,7 +174,7 @@ public abstract class AbstractPwmService implements PwmService
 
 
     protected void scheduleFixedRateJob( final Runnable runnable, final TimeDuration initialDelay, final TimeDuration repeatInterval )
     protected void scheduleFixedRateJob( final Runnable runnable, final TimeDuration initialDelay, final TimeDuration repeatInterval )
     {
     {
-        pwmApplication.getPwmScheduler().scheduleFixedRateJob( new WrappedRunnable( runnable ),
+        PwmScheduler.scheduleFixedRateJob( new WrappedRunnable( runnable ),
                 executorService.get(),
                 executorService.get(),
                 initialDelay,
                 initialDelay,
                 repeatInterval );
                 repeatInterval );
@@ -194,7 +194,7 @@ public abstract class AbstractPwmService implements PwmService
 
 
     protected void scheduleDailyZuluZeroStartJob( final Runnable runnable, final TimeDuration zuluOffset )
     protected void scheduleDailyZuluZeroStartJob( final Runnable runnable, final TimeDuration zuluOffset )
     {
     {
-        pwmApplication.getPwmScheduler().scheduleDailyZuluZeroStartJob( new WrappedRunnable( runnable ),
+        PwmScheduler.scheduleDailyZuluZeroStartJob( new WrappedRunnable( runnable ),
                 executorService.get(),
                 executorService.get(),
                 zuluOffset );
                 zuluOffset );
     }
     }

+ 0 - 11
server/src/main/java/password/pwm/svc/db/DBConfiguration.java

@@ -29,11 +29,8 @@ import password.pwm.config.PwmSetting;
 import password.pwm.config.value.FileValue;
 import password.pwm.config.value.FileValue;
 import password.pwm.data.ImmutableByteArray;
 import password.pwm.data.ImmutableByteArray;
 import password.pwm.util.PasswordData;
 import password.pwm.util.PasswordData;
-import password.pwm.util.java.CollectionUtil;
 
 
-import java.util.Arrays;
 import java.util.Map;
 import java.util.Map;
-import java.util.Set;
 
 
 @Value
 @Value
 @AllArgsConstructor( access = AccessLevel.PRIVATE )
 @AllArgsConstructor( access = AccessLevel.PRIVATE )
@@ -46,7 +43,6 @@ public class DBConfiguration
     private final String columnTypeKey;
     private final String columnTypeKey;
     private final String columnTypeValue;
     private final String columnTypeValue;
     private final ImmutableByteArray jdbcDriver;
     private final ImmutableByteArray jdbcDriver;
-    private final Set<JDBCDriverLoader.ClassLoaderStrategy> classLoaderStrategies;
     private final int maxConnections;
     private final int maxConnections;
     private final int connectionTimeout;
     private final int connectionTimeout;
     private final int keyColumnLength;
     private final int keyColumnLength;
@@ -72,12 +68,6 @@ public class DBConfiguration
             jdbcDriverBytes = null;
             jdbcDriverBytes = null;
         }
         }
 
 
-        final String strategyList = config.readAppProperty( AppProperty.DB_JDBC_LOAD_STRATEGY );
-        final Set<JDBCDriverLoader.ClassLoaderStrategy> strategies = CollectionUtil.readEnumSetFromStringCollection(
-                JDBCDriverLoader.ClassLoaderStrategy.class,
-                Arrays.asList( strategyList.split( "," ) )
-        );
-
         final int maxConnections = Integer.parseInt( config.readAppProperty( AppProperty.DB_CONNECTIONS_MAX ) );
         final int maxConnections = Integer.parseInt( config.readAppProperty( AppProperty.DB_CONNECTIONS_MAX ) );
         final int connectionTimeout = Integer.parseInt( config.readAppProperty( AppProperty.DB_CONNECTIONS_TIMEOUT_MS ) );
         final int connectionTimeout = Integer.parseInt( config.readAppProperty( AppProperty.DB_CONNECTIONS_TIMEOUT_MS ) );
 
 
@@ -93,7 +83,6 @@ public class DBConfiguration
                 config.readSettingAsString( PwmSetting.DATABASE_COLUMN_TYPE_KEY ),
                 config.readSettingAsString( PwmSetting.DATABASE_COLUMN_TYPE_KEY ),
                 config.readSettingAsString( PwmSetting.DATABASE_COLUMN_TYPE_VALUE ),
                 config.readSettingAsString( PwmSetting.DATABASE_COLUMN_TYPE_VALUE ),
                 jdbcDriverBytes,
                 jdbcDriverBytes,
-                strategies,
                 maxConnections,
                 maxConnections,
                 connectionTimeout,
                 connectionTimeout,
                 keyColumnLength,
                 keyColumnLength,

+ 1 - 1
server/src/main/java/password/pwm/svc/db/DatabaseAccessorImpl.java

@@ -340,7 +340,7 @@ class DatabaseAccessorImpl implements DatabaseAccessor
         private PreparedStatement statement;
         private PreparedStatement statement;
         private Map.Entry<String, String> nextValue;
         private Map.Entry<String, String> nextValue;
         private boolean finished;
         private boolean finished;
-        private int counter = ITERATOR_COUNTER.getAndIncrement();
+        private final int counter = ITERATOR_COUNTER.getAndIncrement();
 
 
         DBIterator( final DatabaseTable table )
         DBIterator( final DatabaseTable table )
                 throws DatabaseException
                 throws DatabaseException

+ 3 - 24
server/src/main/java/password/pwm/svc/db/DatabaseService.java

@@ -45,7 +45,7 @@ import password.pwm.util.logging.PwmLogger;
 
 
 import java.sql.Connection;
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
 import java.sql.DatabaseMetaData;
-import java.sql.Driver;
+import java.sql.DriverManager;
 import java.sql.SQLException;
 import java.sql.SQLException;
 import java.time.Instant;
 import java.time.Instant;
 import java.util.ArrayList;
 import java.util.ArrayList;
@@ -70,9 +70,6 @@ public class DatabaseService extends AbstractPwmService implements PwmService
 
 
     private DBConfiguration dbConfiguration;
     private DBConfiguration dbConfiguration;
 
 
-    private Driver driver;
-    private JDBCDriverLoader.DriverLoader jdbcDriverLoader;
-
     private ErrorInformation lastError;
     private ErrorInformation lastError;
 
 
     private AtomicLoopIntIncrementer slotIncrementer;
     private AtomicLoopIntIncrementer slotIncrementer;
@@ -199,21 +196,6 @@ public class DatabaseService extends AbstractPwmService implements PwmService
         setStatus( STATUS.CLOSED );
         setStatus( STATUS.CLOSED );
 
 
         clearCurrentAccessors();
         clearCurrentAccessors();
-
-        try
-        {
-            driver = null;
-        }
-        catch ( final Exception e )
-        {
-            LOGGER.debug( getSessionLabel(), () -> "error while de-registering driver: " + e.getMessage() );
-        }
-
-        if ( jdbcDriverLoader != null )
-        {
-            jdbcDriverLoader.unloadDriver();
-            jdbcDriverLoader = null;
-        }
     }
     }
 
 
     private void clearCurrentAccessors( )
     private void clearCurrentAccessors( )
@@ -358,13 +340,10 @@ public class DatabaseService extends AbstractPwmService implements PwmService
     {
     {
         final String connectionURL = dbConfiguration.getConnectionString();
         final String connectionURL = dbConfiguration.getConnectionString();
 
 
-        final JDBCDriverLoader.DriverWrapper wrapper = JDBCDriverLoader.loadDriver( getPwmApplication(), dbConfiguration );
-        driver = wrapper.getDriver();
-        jdbcDriverLoader = wrapper.getDriverLoader();
-
         try
         try
         {
         {
             LOGGER.debug( getSessionLabel(), () -> "initiating connecting to database " + connectionURL );
             LOGGER.debug( getSessionLabel(), () -> "initiating connecting to database " + connectionURL );
+            JDBCDriverLoader.loadDriver( getPwmApplication(), dbConfiguration );
             final Properties connectionProperties = new Properties();
             final Properties connectionProperties = new Properties();
             if ( dbConfiguration.getUsername() != null && !dbConfiguration.getUsername().isEmpty() )
             if ( dbConfiguration.getUsername() != null && !dbConfiguration.getUsername().isEmpty() )
             {
             {
@@ -375,7 +354,7 @@ public class DatabaseService extends AbstractPwmService implements PwmService
                 connectionProperties.setProperty( "password", dbConfiguration.getPassword().getStringValue() );
                 connectionProperties.setProperty( "password", dbConfiguration.getPassword().getStringValue() );
             }
             }
 
 
-            final Connection connection = driver.connect( connectionURL, connectionProperties );
+            final Connection connection = DriverManager.getConnection( connectionURL, connectionProperties );
             LOGGER.debug( getSessionLabel(), () -> "connected to database " + connectionURL );
             LOGGER.debug( getSessionLabel(), () -> "connected to database " + connectionURL );
 
 
             connection.setAutoCommit( false );
             connection.setAutoCommit( false );

+ 98 - 234
server/src/main/java/password/pwm/svc/db/JDBCDriverLoader.java

@@ -21,47 +21,46 @@
 package password.pwm.svc.db;
 package password.pwm.svc.db;
 
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import org.xeustechnologies.jcl.JarClassLoader;
-import org.xeustechnologies.jcl.JclObjectFactory;
 import password.pwm.PwmApplication;
 import password.pwm.PwmApplication;
-import password.pwm.PwmConstants;
 import password.pwm.data.ImmutableByteArray;
 import password.pwm.data.ImmutableByteArray;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.PwmError;
 import password.pwm.error.PwmError;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.error.PwmUnrecoverableException;
-import password.pwm.util.java.JavaHelper;
 import password.pwm.util.json.JsonFactory;
 import password.pwm.util.json.JsonFactory;
 import password.pwm.util.logging.PwmLogger;
 import password.pwm.util.logging.PwmLogger;
 
 
 import java.io.IOException;
 import java.io.IOException;
-import java.io.OutputStream;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.InvocationTargetException;
 import java.net.URL;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.net.URLClassLoader;
 import java.nio.file.Files;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Path;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
+import java.sql.Connection;
 import java.sql.Driver;
 import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.DriverPropertyInfo;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
-import java.util.Map;
+import java.util.Optional;
+import java.util.Properties;
 import java.util.Set;
 import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
 
 
 public class JDBCDriverLoader
 public class JDBCDriverLoader
 {
 {
 
 
     private static final PwmLogger LOGGER = PwmLogger.forClass( JDBCDriverLoader.class, true );
     private static final PwmLogger LOGGER = PwmLogger.forClass( JDBCDriverLoader.class, true );
 
 
-    static DriverWrapper loadDriver(
+    static Driver loadDriver(
             final PwmApplication pwmApplication,
             final PwmApplication pwmApplication,
             final DBConfiguration dbConfiguration
             final DBConfiguration dbConfiguration
     )
     )
             throws DatabaseException
             throws DatabaseException
     {
     {
-        final Set<ClassLoaderStrategy> strategies = dbConfiguration.getClassLoaderStrategies();
+        final Set<ClassLoaderStrategy> strategies = Set.of( ClassLoaderStrategy.AppPathFileLoader, ClassLoaderStrategy.Classpath );
         LOGGER.trace( () -> "attempting to load jdbc driver using strategies: " + JsonFactory.get().serializeCollection( strategies ) );
         LOGGER.trace( () -> "attempting to load jdbc driver using strategies: " + JsonFactory.get().serializeCollection( strategies ) );
         final List<String> errorMsgs = new ArrayList<>();
         final List<String> errorMsgs = new ArrayList<>();
         for ( final ClassLoaderStrategy strategy : strategies )
         for ( final ClassLoaderStrategy strategy : strategies )
@@ -72,7 +71,7 @@ public class JDBCDriverLoader
                 final Driver driver = loader.loadDriver( pwmApplication, dbConfiguration );
                 final Driver driver = loader.loadDriver( pwmApplication, dbConfiguration );
                 if ( driver != null )
                 if ( driver != null )
                 {
                 {
-                    return new DriverWrapper( driver, loader );
+                    return driver;
                 }
                 }
             }
             }
             catch ( final PwmUnrecoverableException | DatabaseException e )
             catch ( final PwmUnrecoverableException | DatabaseException e )
@@ -88,9 +87,7 @@ public class JDBCDriverLoader
 
 
     public enum ClassLoaderStrategy
     public enum ClassLoaderStrategy
     {
     {
-        XeusLoader( XeusJarClassDriverLoader.class ),
         AppPathFileLoader( AppPathDriverLoader.class ),
         AppPathFileLoader( AppPathDriverLoader.class ),
-        TempFile( TempFileDriverLoader.class ),
         Classpath( JavaClasspathLoader.class ),;
         Classpath( JavaClasspathLoader.class ),;
 
 
         private final Class<? extends DriverLoader> jdbcDriverDriverLoaderClass;
         private final Class<? extends DriverLoader> jdbcDriverDriverLoaderClass;
@@ -119,14 +116,12 @@ public class JDBCDriverLoader
     interface DriverLoader
     interface DriverLoader
     {
     {
         Driver loadDriver( PwmApplication pwmApplication, DBConfiguration dbConfiguration ) throws DatabaseException;
         Driver loadDriver( PwmApplication pwmApplication, DBConfiguration dbConfiguration ) throws DatabaseException;
-
-        void unloadDriver( );
     }
     }
 
 
     private static class JavaClasspathLoader implements DriverLoader
     private static class JavaClasspathLoader implements DriverLoader
     {
     {
 
 
-        private static final PwmLogger LOGGER = PwmLogger.forClass( XeusJarClassDriverLoader.class, true );
+        private static final PwmLogger LOGGER = PwmLogger.forClass( JavaClasspathLoader.class, true );
 
 
         @Override
         @Override
         public Driver loadDriver( final PwmApplication pwmApplication, final DBConfiguration dbConfiguration )
         public Driver loadDriver( final PwmApplication pwmApplication, final DBConfiguration dbConfiguration )
@@ -137,7 +132,7 @@ public class JDBCDriverLoader
             try
             try
             {
             {
                 LOGGER.debug( () -> "loading JDBC database driver from classpath: " + jdbcClassName );
                 LOGGER.debug( () -> "loading JDBC database driver from classpath: " + jdbcClassName );
-                final Driver driver = ( Driver ) Class.forName( jdbcClassName ).getDeclaredConstructor().newInstance();
+                final Driver driver = DriverManager.getDriver( dbConfiguration.getConnectionString() );
 
 
                 LOGGER.debug( () -> "successfully loaded JDBC database driver from classpath: " + jdbcClassName );
                 LOGGER.debug( () -> "successfully loaded JDBC database driver from classpath: " + jdbcClassName );
                 return driver;
                 return driver;
@@ -149,74 +144,16 @@ public class JDBCDriverLoader
                 throw new DatabaseException( errorInformation );
                 throw new DatabaseException( errorInformation );
             }
             }
         }
         }
-
-        @Override
-        public void unloadDriver( )
-        {
-        }
     }
     }
 
 
 
 
-    private static class XeusJarClassDriverLoader implements DriverLoader
-    {
-
-        private static final PwmLogger LOGGER = PwmLogger.forClass( XeusJarClassDriverLoader.class, true );
-
-
-        @Override
-        public Driver loadDriver( final PwmApplication pwmApplication, final DBConfiguration dbConfiguration )
-                throws DatabaseException
-        {
-            final String jdbcClassName = dbConfiguration.getDriverClassname();
-            final ImmutableByteArray jdbcDriverBytes = dbConfiguration.getJdbcDriver();
-            try
-            {
-                LOGGER.debug( () -> "loading JDBC database driver stored in configuration" );
-
-                final JarClassLoader jarClassLoader = AccessController.doPrivileged(
-                        ( PrivilegedAction<JarClassLoader> ) JarClassLoader::new
-                );
-
-                jarClassLoader.add( jdbcDriverBytes.newByteArrayInputStream() );
-                final JclObjectFactory jclObjectFactory = JclObjectFactory.getInstance( true );
-
-                //Create object of loaded class
-                final Driver driver = ( Driver ) jclObjectFactory.create( jarClassLoader, jdbcClassName );
-
-                LOGGER.debug( () -> "successfully loaded JDBC database driver '" + jdbcClassName + "' from application configuration" );
-
-                return driver;
-            }
-            catch ( final Throwable e )
-            {
-                final String errorMsg = "error registering JDBC database driver stored in configuration: " + e.getMessage();
-                final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_DB_UNAVAILABLE, errorMsg );
-                throw new DatabaseException( errorInformation );
-            }
-        }
-
-        @Override
-        public void unloadDriver( )
-        {
-
-        }
-    }
-
-    private static class TempFileDriverLoader implements DriverLoader
+    private static class AppPathDriverLoader implements DriverLoader
     {
     {
+        private static final PwmLogger LOGGER = PwmLogger.forClass( AppPathDriverLoader.class, true );
 
 
-        private static final PwmLogger LOGGER = PwmLogger.forClass( TempFileDriverLoader.class, true );
-
-        private Path tempFile;
-
-        @Override
-
-        // not clear if this is worth it to fix
-        @SuppressFBWarnings( "DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED" )
         public Driver loadDriver( final PwmApplication pwmApplication, final DBConfiguration dbConfiguration )
         public Driver loadDriver( final PwmApplication pwmApplication, final DBConfiguration dbConfiguration )
                 throws DatabaseException
                 throws DatabaseException
         {
         {
-            final String jdbcClassName = dbConfiguration.getDriverClassname();
             final ImmutableByteArray jdbcDriverBytes = dbConfiguration.getJdbcDriver();
             final ImmutableByteArray jdbcDriverBytes = dbConfiguration.getJdbcDriver();
 
 
             if ( jdbcDriverBytes == null || jdbcDriverBytes.size() < 1 )
             if ( jdbcDriverBytes == null || jdbcDriverBytes.size() < 1 )
@@ -225,139 +162,24 @@ public class JDBCDriverLoader
                 final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_DB_UNAVAILABLE, errorMsg );
                 final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_DB_UNAVAILABLE, errorMsg );
                 throw new DatabaseException( errorInformation );
                 throw new DatabaseException( errorInformation );
             }
             }
+
             try
             try
             {
             {
-                LOGGER.debug( () -> "loading JDBC database driver stored in configuration" );
-
-                if ( tempFile == null )
+                if ( !createAndRegisterDriverJar( pwmApplication, dbConfiguration ) )
                 {
                 {
-                    final String prefixName = PwmConstants.PWM_APP_NAME.toLowerCase() + "_jdbcJar_";
-                    tempFile = Files.createTempFile( pwmApplication.getTempDirectory(), prefixName, "jar" );
-                    LOGGER.trace( () -> "created temp file " + tempFile );
+                    return null;
                 }
                 }
-
-                try ( OutputStream outputStream = Files.newOutputStream( tempFile ) )
-                {
-                    JavaHelper.copy( jdbcDriverBytes.newByteArrayInputStream(), outputStream );
-                }
-
-                final URLClassLoader urlClassLoader = new URLClassLoader(
-                        new URL[]
-                                {
-                                        tempFile.toUri().toURL(),
-                                },
-                        this.getClass().getClassLoader()
-                );
-
-                //Create object of loaded class
-                final Class<?> jdbcDriverClass = urlClassLoader.loadClass( jdbcClassName );
-                final Driver driver = ( Driver ) jdbcDriverClass.getDeclaredConstructor().newInstance();
-
-                LOGGER.debug( () -> "successfully loaded JDBC database driver '" + jdbcClassName + "' from application configuration" );
-
-                return driver;
             }
             }
             catch ( final Throwable e )
             catch ( final Throwable e )
             {
             {
-                final String errorMsg = "error registering JDBC database driver stored in configuration: " + e.getMessage();
-                final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_DB_UNAVAILABLE, errorMsg );
-                throw new DatabaseException( errorInformation );
-            }
-        }
-
-        @Override
-        public void unloadDriver( )
-        {
-            if ( tempFile != null )
-            {
-                try
-                {
-                    if ( Files.deleteIfExists( tempFile ) )
-                    {
-                        LOGGER.trace( () -> "removed temporary file " + tempFile );
-                    }
-                }
-                catch ( final IOException e )
-                {
-                    LOGGER.trace( () -> "error removing temporary file " + tempFile + ", error: " + e.getMessage(), e );
-                }
-            }
-            tempFile = null;
-        }
-    }
-
-    private static class AppPathDriverLoader implements DriverLoader
-    {
-
-        private static final PwmLogger LOGGER = PwmLogger.forClass( AppPathDriverLoader.class, true );
-
-        // static cache of classloader to prevent classloader memory leak
-        private static Map<String, ClassLoader> driverCache = new ConcurrentHashMap<>();
-
-
-        @Override
-
-        // not clear if this is worth it to fix
-        @SuppressFBWarnings( "DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED" )
-        public Driver loadDriver( final PwmApplication pwmApplication, final DBConfiguration dbConfiguration )
-                throws DatabaseException
-        {
-            final String jdbcClassName = dbConfiguration.getDriverClassname();
-            final ImmutableByteArray jdbcDriverBytes = dbConfiguration.getJdbcDriver();
-
-            if ( jdbcDriverBytes == null || jdbcDriverBytes.size() < 1 )
-            {
-                final String errorMsg = "jdbc driver file not configured, skipping";
+                final String errorMsg = "error establishing classloader for driver: " + e.getMessage();
                 final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_DB_UNAVAILABLE, errorMsg );
                 final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_DB_UNAVAILABLE, errorMsg );
                 throw new DatabaseException( errorInformation );
                 throw new DatabaseException( errorInformation );
             }
             }
 
 
-            final String jdbcDriverHash;
             try
             try
             {
             {
-                jdbcDriverHash = pwmApplication.getSecureService().hash( jdbcDriverBytes.newByteArrayInputStream() );
-            }
-            catch ( final PwmUnrecoverableException e )
-            {
-                throw new DatabaseException( e.getErrorInformation() );
-            }
-
-            final ClassLoader urlClassLoader;
-            if ( driverCache.containsKey( jdbcDriverHash ) )
-            {
-                urlClassLoader = driverCache.get( jdbcDriverHash );
-                LOGGER.trace( () -> "loaded classloader from static cache" );
-            }
-            else
-            {
-                try
-                {
-                    LOGGER.debug( () -> "loading JDBC database driver stored in configuration" );
-                    final Path tempFile = createOrGetTempJarFile( pwmApplication, jdbcDriverBytes );
-                    urlClassLoader = new URLClassLoader(
-                            new URL[]
-                                    {
-                                            tempFile.toUri().toURL(),
-                                    },
-                            this.getClass().getClassLoader()
-                    );
-                    driverCache.put( jdbcDriverHash, urlClassLoader );
-                }
-                catch ( final Throwable e )
-                {
-                    final String errorMsg = "error establishing classloader for driver: " + e.getMessage();
-                    final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_DB_UNAVAILABLE, errorMsg );
-                    throw new DatabaseException( errorInformation );
-                }
-            }
-
-            try
-            {
-                //Create object of loaded class
-                final Class<?> jdbcDriverClass = urlClassLoader.loadClass( jdbcClassName );
-                final Driver driver = ( Driver ) jdbcDriverClass.getDeclaredConstructor().newInstance();
-                LOGGER.debug( () -> "successfully loaded JDBC database driver '" + jdbcClassName + "' from application configuration" );
-                return driver;
+                return DriverManager.getDriver( dbConfiguration.getConnectionString() );
             }
             }
             catch ( final Throwable e )
             catch ( final Throwable e )
             {
             {
@@ -367,63 +189,105 @@ public class JDBCDriverLoader
             }
             }
         }
         }
 
 
-        @Override
-        public void unloadDriver( )
+        @SuppressFBWarnings( "DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED" )
+        boolean createAndRegisterDriverJar(
+                final PwmApplication pwmApplication,
+                final DBConfiguration dbConfiguration
+        )
+                throws PwmUnrecoverableException, IOException, ClassNotFoundException, NoSuchMethodException,
+                InvocationTargetException, InstantiationException, IllegalAccessException, SQLException
         {
         {
-        }
+            final Optional<Path> pwmTempDir = pwmApplication.getTempDirectory();
+            if ( pwmTempDir.isEmpty() )
+            {
+                return false;
+            }
 
 
-        Path createOrGetTempJarFile( final PwmApplication pwmApplication, final ImmutableByteArray jarBytes )
-                throws PwmUnrecoverableException, IOException
-        {
-            final Path file = pwmApplication.getTempDirectory();
-            final String jarHash = pwmApplication.getSecureService().hash( jarBytes.newByteArrayInputStream() );
+            final byte[] jarBytes = dbConfiguration.getJdbcDriver().copyOf();
+            final String jarHash = pwmApplication.getSecureService().hash( jarBytes );
             final String tempFileName = "jar-" + jarHash + ".jar";
             final String tempFileName = "jar-" + jarHash + ".jar";
-            final Path tempFile = file.resolve( tempFileName );
+            final Path tempFile = pwmTempDir.get().resolve( tempFileName );
+
             if ( Files.exists( tempFile ) )
             if ( Files.exists( tempFile ) )
             {
             {
-                final String fileHash = pwmApplication.getSecureService().hash( tempFile );
-                if ( !jarHash.equals( fileHash ) )
-                {
-                    LOGGER.debug( () -> "existing temp jar file " + tempFile + " has wrong contents, will delete" );
-                    Files.delete( tempFile );
-                }
-            }
-            if ( !Files.exists( tempFile ) )
-            {
-                LOGGER.debug( () -> "creating temp jar file " + tempFile );
-                try ( OutputStream fos = Files.newOutputStream( tempFile ) )
-                {
-                    JavaHelper.copy( jarBytes.newByteArrayInputStream(), fos );
-                }
-            }
-            else
-            {
-                LOGGER.trace( () -> "reusing existing temp jar file " + tempFile );
+                LOGGER.trace( () -> "reusing existing temp jar file and registration: " + tempFile );
+                return true;
             }
             }
 
 
-            return tempFile;
+            LOGGER.debug( () -> "creating temp jar file " + tempFile );
+            Files.write( tempFile, jarBytes );
+
+            // load into classloader
+            final URLClassLoader urlClassLoader = new URLClassLoader(
+                    new URL[]
+                            {
+                                    tempFile.toUri().toURL(),
+                            },
+                    this.getClass().getClassLoader() );
+
+            //Create object of loaded class
+            final Class<?> jdbcDriverClass = urlClassLoader.loadClass( dbConfiguration.getDriverClassname() );
+            final Driver driver = new DriverShim( ( Driver ) jdbcDriverClass.getDeclaredConstructor().newInstance() );
+            LOGGER.debug( () -> "successfully loaded JDBC database driver '" + dbConfiguration.getDriverClassname() + "' from application configuration" );
+            DriverManager.registerDriver( driver );
+            return true;
+
         }
         }
     }
     }
 
 
-    static class DriverWrapper
+    private static class DriverShim implements Driver
     {
     {
         private final Driver driver;
         private final Driver driver;
-        private final DriverLoader driverLoader;
 
 
-        DriverWrapper( final Driver driver, final DriverLoader driverLoader )
+        DriverShim( final Driver driver )
         {
         {
             this.driver = driver;
             this.driver = driver;
-            this.driverLoader = driverLoader;
         }
         }
 
 
-        public Driver getDriver( )
+        @Override
+        public Connection connect( final String url, final Properties info )
+                throws SQLException
         {
         {
-            return driver;
+            return driver.connect( url, info );
         }
         }
 
 
-        public DriverLoader getDriverLoader( )
+        @Override
+        public boolean acceptsURL( final String url )
+                throws SQLException
+        {
+            return driver.acceptsURL( url );
+        }
+
+        @Override
+        public DriverPropertyInfo[] getPropertyInfo( final String url, final Properties info )
+                throws SQLException
+        {
+            return driver.getPropertyInfo( url, info );
+        }
+
+        @Override
+        public int getMajorVersion()
+        {
+            return driver.getMajorVersion();
+        }
+
+        @Override
+        public int getMinorVersion()
+        {
+            return driver.getMinorVersion();
+        }
+
+        @Override
+        public boolean jdbcCompliant()
+        {
+            return driver.jdbcCompliant();
+        }
+
+        @Override
+        public Logger getParentLogger()
+                throws SQLFeatureNotSupportedException
         {
         {
-            return driverLoader;
+            return driver.getParentLogger();
         }
         }
     }
     }
 }
 }

+ 1 - 1
server/src/main/java/password/pwm/svc/event/LocalDbAuditVault.java

@@ -74,7 +74,7 @@ public class LocalDbAuditVault implements AuditVault
 
 
         status = PwmService.STATUS.OPEN;
         status = PwmService.STATUS.OPEN;
         final TimeDuration jobFrequency = TimeDuration.of( 10, TimeDuration.Unit.MINUTES );
         final TimeDuration jobFrequency = TimeDuration.of( 10, TimeDuration.Unit.MINUTES );
-        pwmApplication.getPwmScheduler().scheduleFixedRateJob( new TrimmerThread(), executorService, TimeDuration.SECONDS_10, jobFrequency );
+        PwmScheduler.scheduleFixedRateJob( new TrimmerThread(), executorService, TimeDuration.SECONDS_10, jobFrequency );
     }
     }
 
 
     @Override
     @Override

+ 10 - 4
server/src/main/java/password/pwm/svc/userhistory/DatabaseUserHistory.java

@@ -31,6 +31,7 @@ import password.pwm.svc.db.DatabaseException;
 import password.pwm.svc.db.DatabaseService;
 import password.pwm.svc.db.DatabaseService;
 import password.pwm.svc.db.DatabaseTable;
 import password.pwm.svc.db.DatabaseTable;
 import password.pwm.svc.event.AuditEventType;
 import password.pwm.svc.event.AuditEventType;
+import password.pwm.svc.event.AuditRecordData;
 import password.pwm.svc.event.HelpdeskAuditRecord;
 import password.pwm.svc.event.HelpdeskAuditRecord;
 import password.pwm.svc.event.UserAuditRecord;
 import password.pwm.svc.event.UserAuditRecord;
 import password.pwm.user.UserInfo;
 import password.pwm.user.UserInfo;
@@ -38,8 +39,10 @@ import password.pwm.util.java.CollectionUtil;
 import password.pwm.util.json.JsonFactory;
 import password.pwm.util.json.JsonFactory;
 import password.pwm.util.logging.PwmLogger;
 import password.pwm.util.logging.PwmLogger;
 
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
 import java.util.Optional;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 
 class DatabaseUserHistory implements UserHistoryStore
 class DatabaseUserHistory implements UserHistoryStore
 {
 {
@@ -78,8 +81,9 @@ class DatabaseUserHistory implements UserHistoryStore
         {
         {
             final StoredHistory storedHistory;
             final StoredHistory storedHistory;
             storedHistory = readStoredHistory( guid );
             storedHistory = readStoredHistory( guid );
-            storedHistory.records().add( auditRecord );
-            writeStoredHistory( guid, storedHistory );
+            final List<AuditRecordData> mutableRecordList = new ArrayList<>( storedHistory.records() );
+            mutableRecordList.add( ( AuditRecordData ) auditRecord );
+            writeStoredHistory( guid, new StoredHistory( mutableRecordList ) );
         }
         }
         catch ( final DatabaseException e )
         catch ( final DatabaseException e )
         {
         {
@@ -93,7 +97,9 @@ class DatabaseUserHistory implements UserHistoryStore
         final String userGuid = userInfo.getUserGuid();
         final String userGuid = userInfo.getUserGuid();
         try
         try
         {
         {
-            return readStoredHistory( userGuid ).records();
+            return readStoredHistory( userGuid ).records().stream()
+                    .map( auditRecordData -> ( UserAuditRecord ) auditRecordData )
+                    .collect( Collectors.toList() );
         }
         }
         catch ( final DatabaseException e )
         catch ( final DatabaseException e )
         {
         {
@@ -122,7 +128,7 @@ class DatabaseUserHistory implements UserHistoryStore
     }
     }
 
 
     record StoredHistory(
     record StoredHistory(
-            List<UserAuditRecord> records
+            List<AuditRecordData> records
     )
     )
     {
     {
         StoredHistory
         StoredHistory

+ 8 - 7
server/src/main/java/password/pwm/svc/userhistory/LdapXmlUserHistory.java

@@ -222,10 +222,12 @@ public class LdapXmlUserHistory implements UserHistoryStore
                 return StoredHistory.fromXml( theCor.getPayload() );
                 return StoredHistory.fromXml( theCor.getPayload() );
             }
             }
         }
         }
-        catch ( final ChaiOperationException e )
+        catch ( final Exception e )
         {
         {
-            LOGGER.error( sessionLabel, () -> "ldap error reading user event log: " + e.getMessage() );
+            LOGGER.error( sessionLabel, () -> "error reading user history for "
+                    + userIdentity.toString() + ", error: " + e.getMessage() );
         }
         }
+
         return new StoredHistory();
         return new StoredHistory();
     }
     }
 
 
@@ -295,7 +297,10 @@ public class LdapXmlUserHistory implements UserHistoryStore
             }
             }
         }
         }
 
 
-        public static StoredHistory fromXml( final String input )
+        public static StoredHistory fromXml(
+                final String input
+        )
+                throws IOException
         {
         {
             final StoredHistory returnHistory = new StoredHistory();
             final StoredHistory returnHistory = new StoredHistory();
 
 
@@ -328,10 +333,6 @@ public class LdapXmlUserHistory implements UserHistoryStore
                     } ) );
                     } ) );
                 }
                 }
             }
             }
-            catch ( final IOException e )
-            {
-                LOGGER.error( () -> "error parsing user event history record: " + e.getMessage() );
-            }
             return returnHistory;
             return returnHistory;
         }
         }
     }
     }

+ 1 - 1
server/src/main/java/password/pwm/svc/wordlist/AbstractWordlist.java

@@ -124,7 +124,7 @@ abstract class AbstractWordlist extends AbstractPwmService implements Wordlist,
 
 
         if ( !pwmApplication.getPwmEnvironment().isInternalRuntimeInstance() )
         if ( !pwmApplication.getPwmEnvironment().isInternalRuntimeInstance() )
         {
         {
-            pwmApplication.getPwmScheduler().scheduleFixedRateJob(
+            PwmScheduler.scheduleFixedRateJob(
                     new InspectorJob(), executorService, TimeDuration.SECOND, wordlistConfiguration.getInspectorFrequency() );
                     new InspectorJob(), executorService, TimeDuration.SECOND, wordlistConfiguration.getInspectorFrequency() );
         }
         }
 
 

+ 4 - 7
server/src/main/java/password/pwm/util/PwmScheduler.java

@@ -51,9 +51,8 @@ import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.TimeoutException;
-import java.util.stream.Collectors;
 
 
-public class PwmScheduler
+public final class PwmScheduler
 {
 {
     private static final PwmLogger LOGGER = PwmLogger.forClass( PwmScheduler.class );
     private static final PwmLogger LOGGER = PwmLogger.forClass( PwmScheduler.class );
 
 
@@ -83,7 +82,7 @@ public class PwmScheduler
         executor.submit( runnable );
         executor.submit( runnable );
     }
     }
 
 
-    public void scheduleDailyZuluZeroStartJob(
+    public static void scheduleDailyZuluZeroStartJob(
             final Runnable runnable,
             final Runnable runnable,
             final ScheduledExecutorService executorService,
             final ScheduledExecutorService executorService,
             final TimeDuration zuluOffset
             final TimeDuration zuluOffset
@@ -123,7 +122,7 @@ public class PwmScheduler
 
 
         final List<Future<T>> futures = callables.stream()
         final List<Future<T>> futures = callables.stream()
                 .map( executor::submit )
                 .map( executor::submit )
-                .collect( Collectors.toUnmodifiableList() );
+                .toList();
 
 
 
 
         final List<T> results = new ArrayList<>();
         final List<T> results = new ArrayList<>();
@@ -162,15 +161,13 @@ public class PwmScheduler
     }
     }
 
 
 
 
-    public void scheduleFixedRateJob(
+    public static void scheduleFixedRateJob(
             final Runnable runnable,
             final Runnable runnable,
             final ScheduledExecutorService executor,
             final ScheduledExecutorService executor,
             final TimeDuration initialDelay,
             final TimeDuration initialDelay,
             final TimeDuration frequency
             final TimeDuration frequency
     )
     )
     {
     {
-        checkIfSchedulerClosed();
-
         executor.scheduleAtFixedRate( runnable, initialDelay.asMillis(), frequency.asMillis(), TimeUnit.MILLISECONDS );
         executor.scheduleAtFixedRate( runnable, initialDelay.asMillis(), frequency.asMillis(), TimeUnit.MILLISECONDS );
     }
     }
 
 

+ 7 - 7
server/src/main/java/password/pwm/util/SampleDataGenerator.java

@@ -24,7 +24,6 @@ import com.novell.ldapchai.cr.Answer;
 import password.pwm.PwmApplication;
 import password.pwm.PwmApplication;
 import password.pwm.PwmApplicationMode;
 import password.pwm.PwmApplicationMode;
 import password.pwm.PwmConstants;
 import password.pwm.PwmConstants;
-import password.pwm.PwmDomain;
 import password.pwm.PwmEnvironment;
 import password.pwm.PwmEnvironment;
 import password.pwm.bean.DomainID;
 import password.pwm.bean.DomainID;
 import password.pwm.bean.LoginInfoBean;
 import password.pwm.bean.LoginInfoBean;
@@ -47,6 +46,7 @@ import password.pwm.user.UserInfoBean;
 import password.pwm.util.logging.PwmLogLevel;
 import password.pwm.util.logging.PwmLogLevel;
 import password.pwm.util.macro.MacroRequest;
 import password.pwm.util.macro.MacroRequest;
 
 
+import java.nio.file.Path;
 import java.time.Instant;
 import java.time.Instant;
 import java.util.Collections;
 import java.util.Collections;
 import java.util.Map;
 import java.util.Map;
@@ -158,7 +158,7 @@ public class SampleDataGenerator
                 .build();
                 .build();
     }
     }
 
 
-    public static MacroRequest sampleMacroRequest( final PwmDomain pwmDomain )
+    public static MacroRequest sampleMacroRequest( final Path applicationPath )
             throws PwmUnrecoverableException
             throws PwmUnrecoverableException
     {
     {
         final UserInfo targetUserInfoBean = sampleTargetUserInfo();
         final UserInfo targetUserInfoBean = sampleTargetUserInfo();
@@ -172,7 +172,7 @@ public class SampleDataGenerator
         loginInfoBean.setUserCurrentPassword( PasswordData.forStringValue( "PaSSw0rd" ) );
         loginInfoBean.setUserCurrentPassword( PasswordData.forStringValue( "PaSSw0rd" ) );
 
 
         return MacroRequest.builder()
         return MacroRequest.builder()
-                .pwmApplication( makeSamplePwmApp( ) )
+                .pwmApplication( makeSamplePwmApp( applicationPath ) )
                 .userInfo( userInfoBean )
                 .userInfo( userInfoBean )
                 .targetUserInfo( targetUserInfoBean )
                 .targetUserInfo( targetUserInfoBean )
                 .loginInfoBean( loginInfoBean )
                 .loginInfoBean( loginInfoBean )
@@ -196,18 +196,18 @@ public class SampleDataGenerator
         return AppConfig.forStoredConfig( modifier.newStoredConfiguration() );
         return AppConfig.forStoredConfig( modifier.newStoredConfiguration() );
     }
     }
 
 
-    private static PwmApplication makeSamplePwmApp()
+    private static PwmApplication makeSamplePwmApp( final Path applicationPath )
             throws PwmUnrecoverableException
             throws PwmUnrecoverableException
     {
     {
-        return makeSamplePwmApp( makeConfig() );
+        return makeSamplePwmApp( makeConfig(), applicationPath );
     }
     }
 
 
-    private static PwmApplication makeSamplePwmApp( final AppConfig appConfig )
+    private static PwmApplication makeSamplePwmApp( final AppConfig appConfig, final Path applicationPath )
             throws PwmUnrecoverableException
             throws PwmUnrecoverableException
     {
     {
         final PwmEnvironment pwmEnvironment = PwmEnvironment.builder()
         final PwmEnvironment pwmEnvironment = PwmEnvironment.builder()
                 .config( appConfig )
                 .config( appConfig )
-                .applicationPath( null )
+                .applicationPath( applicationPath )
                 .applicationMode( PwmApplicationMode.READ_ONLY )
                 .applicationMode( PwmApplicationMode.READ_ONLY )
                 .internalRuntimeInstance( true )
                 .internalRuntimeInstance( true )
                 .build();
                 .build();

+ 0 - 1
server/src/main/resources/password/pwm/AppProperty.properties

@@ -78,7 +78,6 @@ configEditor.settingFunction.timeoutMs=5000
 configGuide.idleTimeoutSeconds=3600
 configGuide.idleTimeoutSeconds=3600
 configManager.zipDebug.maxLogBytes=50000000
 configManager.zipDebug.maxLogBytes=50000000
 configManager.zipDebug.maxLogSeconds=120
 configManager.zipDebug.maxLogSeconds=120
-db.jdbcLoadStrategy=AppPathFileLoader,Classpath
 db.connections.max=5
 db.connections.max=5
 db.connections.timeoutMs=30000
 db.connections.timeoutMs=30000
 db.connections.watchdogFrequencySeconds=30
 db.connections.watchdogFrequencySeconds=30

+ 2 - 1
server/src/test/java/password/pwm/svc/event/LdapXmlUserHistoryTest.java

@@ -54,7 +54,8 @@ public class LdapXmlUserHistoryTest
         final PwmDomain pwmDomain = pwmApplication.domains().get( DomainID.DOMAIN_ID_DEFAULT );
         final PwmDomain pwmDomain = pwmApplication.domains().get( DomainID.DOMAIN_ID_DEFAULT );
         final ResourceBundle bundle = ResourceBundle.getBundle( LdapXmlUserHistoryTest.class.getName() );
         final ResourceBundle bundle = ResourceBundle.getBundle( LdapXmlUserHistoryTest.class.getName() );
         final String xmlValue1 =  bundle.getString( "xmlValue1" );
         final String xmlValue1 =  bundle.getString( "xmlValue1" );
-        final LdapXmlUserHistory.StoredHistory storedHistory = LdapXmlUserHistory.StoredHistory.fromXml( xmlValue1 );
+        final LdapXmlUserHistory.StoredHistory storedHistory = LdapXmlUserHistory.StoredHistory
+                .fromXml( xmlValue1 );
 
 
         final List<UserAuditRecord> auditEventList = storedHistory.asAuditRecords(
         final List<UserAuditRecord> auditEventList = storedHistory.asAuditRecords(
                 AuditRecordFactory.make( SessionLabel.TEST_SESSION_LABEL,  pwmDomain ), SampleDataGenerator.sampleUserData() );
                 AuditRecordFactory.make( SessionLabel.TEST_SESSION_LABEL,  pwmDomain ), SampleDataGenerator.sampleUserData() );

+ 6 - 1
server/src/test/java/password/pwm/util/macro/MacroTest.java

@@ -23,23 +23,28 @@ package password.pwm.util.macro;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
 import password.pwm.PwmConstants;
 import password.pwm.PwmConstants;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.util.SampleDataGenerator;
 import password.pwm.util.SampleDataGenerator;
 
 
+import java.nio.file.Path;
 import java.time.Duration;
 import java.time.Duration;
 import java.time.Instant;
 import java.time.Instant;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeUnit;
 
 
 public class MacroTest
 public class MacroTest
 {
 {
+    @TempDir
+    public Path temporaryFolder;
+
     private MacroRequest macroRequest;
     private MacroRequest macroRequest;
 
 
     @BeforeEach
     @BeforeEach
     public void setUp() throws PwmUnrecoverableException
     public void setUp() throws PwmUnrecoverableException
     {
     {
-        macroRequest = SampleDataGenerator.sampleMacroRequest( null );
+        macroRequest = SampleDataGenerator.sampleMacroRequest( temporaryFolder );
     }
     }
 
 
 
 

+ 0 - 10
webapp/pom.xml

@@ -262,16 +262,6 @@
             <artifactId>pwm-client</artifactId>
             <artifactId>pwm-client</artifactId>
             <version>${project.version}</version>
             <version>${project.version}</version>
         </dependency>
         </dependency>
-        <dependency>
-            <groupId>org.webjars.npm</groupId>
-            <artifactId>tinymce</artifactId>
-            <version>6.3.1</version>
-        </dependency>
-        <dependency>
-            <groupId>org.webjars.npm</groupId>
-            <artifactId>jodit</artifactId>
-            <version>3.24.2</version>
-        </dependency>
         <dependency>
         <dependency>
             <groupId>org.webjars.npm</groupId>
             <groupId>org.webjars.npm</groupId>
             <artifactId>dojo</artifactId>
             <artifactId>dojo</artifactId>

+ 0 - 17
webapp/src/main/webapp/WEB-INF/jsp/admin-dashboard.jsp

@@ -229,23 +229,6 @@
                                 <% } %>
                                 <% } %>
                             </td>
                             </td>
                         </tr>
                         </tr>
-                        <tr>
-                            <td class="key">
-                                Dojo API Version
-                            </td>
-                            <td>
-                                <span id="dojoVersionSpan"></span>
-                                <pwm:script>
-                                    <script type="text/javascript">
-                                        PWM_GLOBAL['startupFunctions'].push(function(){
-                                            require(["dojo"],function(dojo){
-                                                dojo.byId('dojoVersionSpan').innerHTML = dojo.version;
-                                            });
-                                        });
-                                    </script>
-                                </pwm:script>
-                            </td>
-                        </tr>
                         <tr>
                         <tr>
                             <td class="key">
                             <td class="key">
                                 License Information
                                 License Information

+ 1 - 1
webapp/src/main/webapp/public/resources/js/main.js

@@ -190,7 +190,7 @@ PWM_MAIN.initPage = function() {
             try {
             try {
                 startupFunction();
                 startupFunction();
             } catch(e) {
             } catch(e) {
-                console.error('error executing startup function: ' + e);
+                console.error('error executing startup function: ' + e,e);
             }
             }
         })
         })
     });
     });