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

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new 1e8dc4cba9 More effort in making log messages less numerous and more 
relevant when the EPSG database is not available.
1e8dc4cba9 is described below

commit 1e8dc4cba94b419a85fb2479bf256a20ef687752
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Sat Oct 5 17:21:22 2024 +0200

    More effort in making log messages less numerous and more relevant when the 
EPSG database is not available.
---
 endorsed/build.gradle.kts                          |  1 +
 .../apache/sis/metadata/sql/MetadataSource.java    |  3 +
 .../sis/metadata/sql/privy/ScriptRunner.java       | 20 ++----
 .../factory/GeodeticAuthorityFactory.java          |  4 +-
 .../sis/referencing/factory/sql/EPSGFactory.java   | 13 ++--
 .../sis/referencing/factory/sql/EPSGInstaller.java | 19 ++---
 .../factory/sql/InstallationScriptProvider.java    | 83 +++++++++++++---------
 .../referencing/factory/sql/EPSGInstallerTest.java |  2 +-
 .../org/apache/sis/util/resources/Messages.java    |  6 ++
 .../apache/sis/util/resources/Messages.properties  |  1 +
 .../sis/util/resources/Messages_fr.properties      |  1 +
 incubator/build.gradle.kts                         |  1 +
 .../sis/resources/embedded/EmbeddedResources.java  |  3 +-
 13 files changed, 92 insertions(+), 65 deletions(-)

diff --git a/endorsed/build.gradle.kts b/endorsed/build.gradle.kts
index c4252f8581..ffd4adcfd4 100644
--- a/endorsed/build.gradle.kts
+++ b/endorsed/build.gradle.kts
@@ -206,6 +206,7 @@ tasks.test {
         events("FAILED", "STANDARD_OUT", "STANDARD_ERROR")
         setExceptionFormat("FULL")
     }
+    systemProperty("java.awt.headless", "true")
     systemProperty("junit.jupiter.execution.parallel.enabled", "true")
     systemProperty("junit.jupiter.execution.parallel.mode.default", 
"concurrent")
     systemProperty("junit.jupiter.execution.parallel.mode.classes.default", 
"concurrent")
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/MetadataSource.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/MetadataSource.java
index ede490d8a9..8f2367c401 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/MetadataSource.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/MetadataSource.java
@@ -374,6 +374,7 @@ public class MetadataSource implements AutoCloseable {
     {
         ArgumentChecks.ensureNonNull("standard",   standard);
         ArgumentChecks.ensureNonNull("dataSource", dataSource);
+        @SuppressWarnings("LocalVariableHidesMemberVariable")
         ClassLoader classloader;
         Integer maxStatements;
 
@@ -453,6 +454,7 @@ public class MetadataSource implements AutoCloseable {
      * @throws SQLException if an error occurred while inserting the metadata.
      */
     final synchronized void install() throws IOException, SQLException {
+        @SuppressWarnings("LocalVariableHidesMemberVariable")
         final Connection connection = connection();
         final DatabaseMetaData md = connection.getMetaData();
         if (md.storesUpperCaseIdentifiers()) {
@@ -541,6 +543,7 @@ public class MetadataSource implements AutoCloseable {
         if (tableName == null) {
             tableName = getTableName(type);
         }
+        @SuppressWarnings("LocalVariableHidesMemberVariable")
         final SQLBuilder helper = helper();
         final String query = helper.clear().append("SELECT * FROM ")
                 .appendIdentifier(schema, tableName).append(" WHERE ")
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/ScriptRunner.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/ScriptRunner.java
index b8785b9cce..8697ccaf2d 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/ScriptRunner.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/ScriptRunner.java
@@ -35,9 +35,9 @@ import java.sql.Statement;
 import java.sql.Connection;
 import java.sql.SQLException;
 import java.sql.DatabaseMetaData;
-import org.apache.sis.util.Debug;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.CharSequences;
+import org.apache.sis.util.privy.Strings;
 import org.apache.sis.util.resources.Errors;
 
 
@@ -241,21 +241,18 @@ public class ScriptRunner implements AutoCloseable {
      * Name of the SQL script under execution, or {@code null} if unknown.
      * This is used only for error reporting.
      */
-    @Debug
     private String currentFile;
 
     /**
      * The line number of the SQL statement being executed. The first line in 
a file is numbered 1.
      * This is used only for error reporting.
      */
-    @Debug
     private int currentLine;
 
     /**
      * The SQL statement being executed.
      * This is used only for error reporting.
      */
-    @Debug
     private String currentSQL;
 
     /**
@@ -464,7 +461,7 @@ public class ScriptRunner implements AutoCloseable {
         if (in == null) {
             throw new 
FileNotFoundException(Errors.format(Errors.Keys.FileNotFound_1, filename));
         }
-        try (BufferedReader reader = new LineNumberReader(new 
InputStreamReader(in, StandardCharsets.UTF_8))) {
+        try (var reader = new LineNumberReader(new InputStreamReader(in, 
StandardCharsets.UTF_8))) {
             return run(filename, reader);
         }
     }
@@ -487,7 +484,7 @@ public class ScriptRunner implements AutoCloseable {
         int     statementCount     = 0;         // For informative purpose 
only.
         int     posOpeningQuote    = -1;        // -1 if we are not inside a 
text.
         boolean isInsideIdentifier = false;
-        final StringBuilder buffer = new StringBuilder();
+        final var buffer = new StringBuilder();
         String line;
         while ((line = in.readLine()) != null) {
             /*
@@ -812,7 +809,7 @@ parseLine:  while (pos < length) {
                     (currentLine != 0) ? currentLine : '?');
         }
         if (currentSQL != null) {
-            final StringBuilder buffer = new StringBuilder();
+            final var buffer = new StringBuilder();
             if (position != null) {
                 buffer.append(position).append('\n');
             }
@@ -822,15 +819,12 @@ parseLine:  while (pos < length) {
     }
 
     /**
-     * Returns a string representation of this runner for debugging purpose. 
Current implementation returns the
-     * current position in the script being executed, and the SQL statement. 
This method may be invoked after a
-     * {@link SQLException} occurred in order to determine the line in the SQL 
script that caused the error.
+     * Returns a string representation of this runner for debugging purpose.
      *
-     * @return the current position in the script being executed.
+     * @return a string representation for debugging purpose.
      */
-    @Debug
     @Override
     public String toString() {
-        return status(null);
+        return Strings.toString(getClass(), "status", status(null));
     }
 }
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
index e2d7464def..55a356df52 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
@@ -1324,8 +1324,8 @@ public abstract class GeodeticAuthorityFactory extends 
AbstractFactory implement
      */
     @Override
     public String toString() {
-        final StringBuilder buffer = new 
StringBuilder(Classes.getShortClassName(this))
-                
.append("[“").append(Citations.getIdentifier(getAuthority())).append('”');
+        final var buffer = new StringBuilder(Classes.getShortClassName(this));
+        // Do not append `getAuthority()` because it may perform database 
access.
         appendStringTo(buffer);
         return buffer.append(']').toString();
     }
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGFactory.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGFactory.java
index 50fb583cb1..420f8dc5f9 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGFactory.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGFactory.java
@@ -380,13 +380,13 @@ public class EPSGFactory extends 
ConcurrentAuthorityFactory<EPSGDataAccess> impl
     public synchronized void install(final Connection connection) throws 
UnavailableFactoryException {
         String    message = null;
         Exception failure = null;
+        boolean   success = false;
         try (EPSGInstaller installer = new 
EPSGInstaller(Objects.requireNonNull(connection))) {
             final boolean ac = connection.getAutoCommit();
             if (ac) {
                 connection.setAutoCommit(false);
             }
             try {
-                boolean success = false;
                 try {
                     if (!"".equals(schema)) {                                  
         // Schema may be null.
                         installer.setSchema(schema != null ? schema : 
Constants.EPSG);
@@ -394,8 +394,7 @@ public class EPSGFactory extends 
ConcurrentAuthorityFactory<EPSGDataAccess> impl
                             installer.prependNamespace(catalog);
                         }
                     }
-                    installer.run(scriptProvider, locale);
-                    success = true;
+                    success = installer.run(scriptProvider, locale);
                 } finally {
                     if (ac) {
                         if (success) {
@@ -411,10 +410,14 @@ public class EPSGFactory extends 
ConcurrentAuthorityFactory<EPSGDataAccess> impl
                 failure = e;
             }
         } catch (SQLException e) {
-            message = 
Messages.forLocale(locale).getString(Messages.Keys.CanNotCreateSchema_1, 
Constants.EPSG);
             failure = e;
         }
-        if (failure != null) {
+        if (!success) {
+            if (message == null) {
+                message = Messages.forLocale(locale).getString(
+                        (failure != null) ? Messages.Keys.CanNotCreateSchema_1
+                                          : Messages.Keys.NoDataSourceFound_1, 
Constants.EPSG);
+            }
             /*
              * Derby sometimes wraps SQLException into another SQLException.  
For making the stack strace a
              * little bit simpler, keep only the root cause provided that the 
exception type is compatible.
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGInstaller.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGInstaller.java
index 23f169f240..9812eaa539 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGInstaller.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGInstaller.java
@@ -225,17 +225,21 @@ final class EPSGInstaller extends ScriptRunner {
      *
      * @param  scriptProvider  user-provided scripts, or {@code null} for 
automatic lookup.
      * @param  locale          the locale for information or warning messages, 
if any.
+     * @return whether the database has been installed.
      * @throws FileNotFoundException if a SQL script has not been found.
      * @throws IOException  if another error occurred while reading an input.
      * @throws SQLException if an error occurred while executing a SQL 
statement.
      */
-    public void run(InstallationResources scriptProvider, final Locale locale) 
throws SQLException, IOException {
+    public boolean run(InstallationResources scriptProvider, final Locale 
locale) throws SQLException, IOException {
         long time = System.nanoTime();
-        
InstallationScriptProvider.log(Messages.forLocale(locale).getLogRecord(Level.INFO,
-                Messages.Keys.CreatingSchema_2, EPSG, 
SQLUtilities.getSimplifiedURL(getConnection().getMetaData())));
         if (scriptProvider == null) {
             scriptProvider = lookupProvider(locale);
+            if (scriptProvider == null) {
+                return false;
+            }
         }
+        
InstallationScriptProvider.log(Messages.forLocale(locale).getLogRecord(Level.INFO,
+                Messages.Keys.CreatingSchema_2, EPSG, 
SQLUtilities.getSimplifiedURL(getConnection().getMetaData())));
         final String[] scripts = scriptProvider.getResourceNames(EPSG);
         int numRows = 0;
         for (int i=0; i<scripts.length; i++) {
@@ -247,6 +251,7 @@ final class EPSGInstaller extends ScriptRunner {
         InstallationScriptProvider.log(Messages.forLocale(locale).getLogRecord(
                 PerformanceLevel.forDuration(time, TimeUnit.NANOSECONDS),
                 Messages.Keys.InsertDuration_2, numRows, time / (float) 
Constants.NANOS_PER_SECOND));
+        return true;
     }
 
     /**
@@ -266,6 +271,7 @@ final class EPSGInstaller extends ScriptRunner {
      * </ol>
      *
      * @param  locale  the locale for information or warning messages, if any.
+     * @return the SQL preferred script provider, or {@code null} if none.
      */
     private static InstallationResources lookupProvider(final Locale locale) 
throws IOException {
         InstallationResources fallback = null;
@@ -284,11 +290,8 @@ final class EPSGInstaller extends ScriptRunner {
          * the user if (s)he accepts EPSG terms of use. But before to use 
those fallbacks, check if the
          * data have not been downloaded manually in the 
"$SIS_DATA/Databases/ExternalSources" directory.
          */
-        final InstallationResources manual = new 
InstallationScriptProvider.Default(locale);
-        if (fallback != null && manual.getAuthorities().isEmpty()) {
-            return fallback;
-        }
-        return manual;
+        final var manual = new InstallationScriptProvider.Default(locale);
+        return manual.getAuthorities().isEmpty() ? fallback : manual;
     }
 
     /**
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java
index 8f6ea07f73..d7265cbb8e 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java
@@ -32,6 +32,7 @@ import java.nio.charset.StandardCharsets;
 import java.nio.file.DirectoryStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.NoSuchFileException;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.setup.InstallationResources;
@@ -62,7 +63,7 @@ import org.apache.sis.util.privy.Constants;
  * </ol>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.4
+ * @version 1.5
  * @since   0.7
  */
 public abstract class InstallationScriptProvider extends InstallationResources 
{
@@ -208,16 +209,21 @@ public abstract class InstallationScriptProvider extends 
InstallationResources {
             throw new 
IllegalStateException(Resources.format(Resources.Keys.UnknownAuthority_1, 
authority));
         }
         String name = resources[resource];
-        final InputStream in;
+        InputStream in;
+        NoSuchFileException cause = null;
         if (PREPARE.equals(name) || FINISH.equals(name)) {
             name = authority + '_' + name + ".sql";
             in = InstallationScriptProvider.class.getResourceAsStream(name);
-        } else {
+        } else try {
             in = openStream(name);
-            name = name.concat(".sql");
+        } catch (NoSuchFileException e) {
+            cause = e;
+            in = null;
         }
         if (in == null) {
-            throw new 
FileNotFoundException(Errors.format(Errors.Keys.FileNotFound_1, name));
+            var e = new 
FileNotFoundException(Errors.format(Errors.Keys.FileNotFound_1, name));
+            e.initCause(cause);
+            throw e;
         }
         return new LineNumberReader(new InputStreamReader(in, 
StandardCharsets.UTF_8));
     }
@@ -267,7 +273,7 @@ public abstract class InstallationScriptProvider extends 
InstallationResources {
 
 
     /**
-     * The default implementation which use the scripts in the {@code 
$SIS_DATA/Databases/ExternalSources}
+     * The default implementation which uses the scripts in the {@code 
$SIS_DATA/Databases/ExternalSources}
      * directory, if present. This class expects the files to have those exact 
names where {@code *} stands
      * for any characters provided that there is no ambiguity:
      *
@@ -284,7 +290,7 @@ public abstract class InstallationScriptProvider extends 
InstallationResources {
         /**
          * The directory containing the scripts, or {@code null} if it does 
not exist.
          */
-        private Path directory;
+        private final Path directory;
 
         /**
          * Index of the first real file in the array given to the constructor.
@@ -305,44 +311,53 @@ public abstract class InstallationScriptProvider extends 
InstallationResources {
                     "FKeys",
                     FINISH);
 
-            Path dir = DataDirectory.DATABASES.getDirectory();
-            if (dir != null) {
-                dir = dir.resolve("ExternalSources");
-                if (Files.isDirectory(dir)) {
-                    final String[] resources = super.resources;
-                    final String[] found = new String[resources.length - 
FIRST_FILE - 1];
-                    try (DirectoryStream<Path> stream = 
Files.newDirectoryStream(dir, "EPSG_*.sql")) {
-                        for (final Path path : stream) {
-                            final String name = path.getFileName().toString();
-                            for (int i=0; i<found.length; i++) {
-                                final String part = resources[FIRST_FILE + i];
-                                if (name.contains(part)) {
-                                    if (found[i] != null) {
-                                        log(Errors.forLocale(locale)
-                                                  .getLogRecord(Level.WARNING, 
Errors.Keys.DuplicatedFileReference_1, part));
-                                        return;   // Stop the search because 
of duplicated file.
-                                    }
+            final String[] resources = super.resources;
+            final String[] found = new String[resources.length - (FIRST_FILE + 
1)];
+            @SuppressWarnings("LocalVariableHidesMemberVariable")
+            Path directory = DataDirectory.DATABASES.getDirectory();
+            if (directory == null || Files.isDirectory(directory = 
directory.resolve("ExternalSources"))) {
+                try (DirectoryStream<Path> stream = 
Files.newDirectoryStream(directory, "EPSG_*.sql")) {
+                    for (final Path path : stream) {
+                        final String name = path.getFileName().toString();
+                        for (int i=0; i<found.length; i++) {
+                            final String part = resources[FIRST_FILE + i];
+                            if (name.contains(part)) {
+                                if (found[i] == null) {
                                     found[i] = name;
+                                } else {
+                                    log(Errors.forLocale(locale)
+                                              .getLogRecord(Level.WARNING, 
Errors.Keys.DuplicatedFileReference_1, part));
                                 }
                             }
                         }
                     }
-                    for (int i=0; i<found.length; i++) {
-                        final String file = found[i];
-                        if (file != null) {
-                            resources[FIRST_FILE + i] = file;
-                        } else {
-                            dir = null;
-                        }
-                    }
-                    directory = dir;
                 }
+            } else {
+                directory = null;
+            }
+            this.directory = directory;
+            /*
+             * Store the actual file names including the target database and 
EPSG dataset version. Example:
+             *
+             *   - PostgreSQL_Table_Script.sql
+             *   - PostgreSQL_Data_Script.sql
+             *   - PostgreSQL_FKey_Script.sql
+             *
+             * If a file was not found, use the "EPSG_Foo_Script.sql" name 
pattern for giving some hints
+             * to users about which file was expected. This filename will 
appear in the exception message.
+             */
+            for (int i=0; i<found.length; i++) {
+                String file = found[i];
+                if (file == null) {
+                    file = "EPSG_" + resources[FIRST_FILE + i] + "_Script.sql";
+                }
+                resources[FIRST_FILE + i] = file;
             }
         }
 
         /**
          * Returns {@code "EPSG"} if the scripts exist in the {@code 
ExternalSources} subdirectory,
-         * or {@code "unavailable"} otherwise.
+         * or an empty set otherwise.
          *
          * @return {@code "EPSG"} if the SQL scripts for installing the EPSG 
dataset are available,
          *         or an empty set otherwise.
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java
index c028bca377..5822892e0a 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java
@@ -104,7 +104,7 @@ public final class EPSGInstallerTest extends 
TestCaseWithLogs {
      * or skip the JUnit test if those scripts are not found.
      */
     private static InstallationScriptProvider getScripts() throws IOException {
-        final InstallationScriptProvider scripts = new 
InstallationScriptProvider.Default(null);
+        final var scripts = new InstallationScriptProvider.Default(null);
         assumeTrue(scripts.getAuthorities().contains(Constants.EPSG),
                 "EPSG scripts not found in Databases/ExternalSources 
directory.");
         return scripts;
diff --git 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Messages.java
 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Messages.java
index f3808051b5..2a661986a5 100644
--- 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Messages.java
+++ 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Messages.java
@@ -191,6 +191,12 @@ public class Messages extends IndexedResourceBundle {
          */
         public static final short LocalesDiscarded = 25;
 
+        /**
+         * No source of {0} data has been found. Those data may require an 
optional module or manual
+         * installation.
+         */
+        public static final short NoDataSourceFound_1 = 37;
+
         /**
          * This “{0}” formatting is a departure from standard format.
          */
diff --git 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Messages.properties
 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Messages.properties
index 4b67fa81ba..d9fe0e2450 100644
--- 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Messages.properties
+++ 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Messages.properties
@@ -43,6 +43,7 @@ IncompleteParsing_1              = Parsing of \u201c{0}\u201d 
done, but some ele
 InsertDuration_2                 = Inserted {0} records in {1} seconds.
 JNDINotSpecified_1               = No object associated to the \u201c{0}\u201d 
JNDI name.
 LocalesDiscarded                 = Text were discarded for some locales.
+NoDataSourceFound_1              = No source of {0} data has been found. Those 
data may require an optional module or manual installation.
 OptionalModuleNotFound_1         = Optional module \u201c{0}\u201d requested 
but not found.
 PossibleInconsistency_1          = Possible inconsistency in \u201c{0}\u201d.
 PropertyHiddenBy_2               = Property \u201c{0}\u201d is hidden by 
\u201c{1}\u201d.
diff --git 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Messages_fr.properties
 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Messages_fr.properties
index 2a30ab9829..ac6e9a2d99 100644
--- 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Messages_fr.properties
+++ 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Messages_fr.properties
@@ -50,6 +50,7 @@ IncompleteParsing_1              = La lecture de 
\u00ab\u202f{0}\u202f\u00bb a \
 InsertDuration_2                 = {0} enregistrements ont \u00e9t\u00e9 
ajout\u00e9s en {1} secondes.
 JNDINotSpecified_1               = Aucun objet n\u2019est associ\u00e9 au nom 
JNDI \u00ab\u202f{0}\u202f\u00bb.
 LocalesDiscarded                 = Des textes ont \u00e9t\u00e9 ignor\u00e9s 
pour certaines langues.
+NoDataSourceFound_1              = Aucune source de donn\u00e9es {0} n\u2019a 
\u00e9t\u00e9 trouv\u00e9e. Ces donn\u00e9es peuvent n\u00e9cessiter un module 
optionnel ou une installation manuelle.
 OptionalModuleNotFound_1         = Le module optionnel 
\u00ab\u202f{0}\u202f\u00bb a \u00e9t\u00e9 demand\u00e9 mais n\u2019a pas 
\u00e9t\u00e9 trouv\u00e9.
 PossibleInconsistency_1           = Il y a possiblement une incoh\u00e9rence 
dans \u00ab\u202f{0}\u202f\u00bb.
 PropertyHiddenBy_2               = La propri\u00e9t\u00e9 
\u00ab\u202f{0}\u202f\u00bb est masqu\u00e9e par \u00ab\u202f{1}\u202f\u00bb.
diff --git a/incubator/build.gradle.kts b/incubator/build.gradle.kts
index 85c219f390..36f3496396 100644
--- a/incubator/build.gradle.kts
+++ b/incubator/build.gradle.kts
@@ -148,6 +148,7 @@ tasks.test {
         events("FAILED", "STANDARD_OUT", "STANDARD_ERROR")
         setExceptionFormat("FULL")
     }
+    systemProperty("java.awt.headless", "true")
     systemProperty("junit.jupiter.execution.parallel.enabled", "true")
     systemProperty("junit.jupiter.execution.parallel.mode.default", 
"concurrent")
     systemProperty("junit.jupiter.execution.parallel.mode.classes.default", 
"concurrent")
diff --git 
a/optional/src/org.apache.sis.referencing.database/main/org/apache/sis/resources/embedded/EmbeddedResources.java
 
b/optional/src/org.apache.sis.referencing.database/main/org/apache/sis/resources/embedded/EmbeddedResources.java
index fade9c8e45..c53faee85b 100644
--- 
a/optional/src/org.apache.sis.referencing.database/main/org/apache/sis/resources/embedded/EmbeddedResources.java
+++ 
b/optional/src/org.apache.sis.referencing.database/main/org/apache/sis/resources/embedded/EmbeddedResources.java
@@ -17,7 +17,6 @@
 package org.apache.sis.resources.embedded;
 
 import java.util.Set;
-import java.util.Collections;
 import java.util.Locale;
 import java.io.BufferedReader;
 import java.io.InputStreamReader;
@@ -63,7 +62,7 @@ public class EmbeddedResources extends InstallationResources {
      */
     @Override
     public Set<String> getAuthorities() {
-        return Collections.singleton(MetadataServices.EMBEDDED);
+        return Set.of(MetadataServices.EMBEDDED);
     }
 
     /**

Reply via email to