Repository: quarkusio/quarkus
Issue: Class PostgreSQL10Dialect not found on Quarkus in Google App Engine java11?

### Describe the bug

I wanted to deploy my quarkus application including hibernate panache to GCP app engine standard and got the error: Class PostgreSQL10Dialect not found on Quarkus


### Expected behavior

Successful startup of quarkus on GCP app engine standard

### Actual behavior

I've set up my quarkus application regarding to https://quarkus.io/guides/deploying-to-google-cloud 
Created a Cloud SQL instance.
And happily deployed the java11 app the first time to GAE. :-)

But - on startup quarkus fails with this reason:
```
	Caused by: java.lang.ClassNotFoundException: org.hibernate.dialect.PostgreSQL10Dialect 
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:398)
	at io.quarkus.hibernate.orm.runtime.service.FlatClassLoaderService.classForName(FlatClassLoaderService.java:36)
```

Looking at the jar:
```
$ jar tvf foodie-1.0-SNAPSHOT-runner.jar | fgrep PostgreSQL10Dialect
  1184 Tue Sep 28 20:12:07 CEST 2021 io/quarkus/hibernate/orm/runtime/dialect/QuarkusPostgreSQL10Dialect.class
   990 Tue Sep 28 20:12:08 CEST 2021 org/hibernate/dialect/PostgreSQL10Dialect.class
```

Any hints how to proceed?

application.properties:
```
quarkus.package.type=uber-jar
quarkus.datasource.db-kind=other 
%dev.quarkus.datasource.jdbc.url=jdbc:postgresql:///quarkus
quarkus.datasource.jdbc.url=jdbc:postgresql:///quarkus
quarkus.datasource.jdbc.driver=org.postgresql.Driver
quarkus.datasource.jdbc.additional-jdbc-properties.cloudSqlInstance=addlogic-foodiefnf-1:europe-west3:quarkus 
quarkus.datasource.jdbc.additional-jdbc-properties.socketFactory=com.google.cloud.sql.postgres.SocketFactory
quarkus.hibernate-orm.dialect=org.hibernate.dialect.PostgreSQL10Dialect 
```

Extract from pom.xml:
```
		<maven.compiler.target>11</maven.compiler.target>
		<quarkus-plugin.version>2.2.3.Final</quarkus-plugin.version>
		<quarkus.platform.artifact-id>quarkus-universe-bom</quarkus.platform.artifact-id>
		<quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
		<quarkus.platform.version>2.2.3.Final</quarkus.platform.version>
		<postgres-socket-factory.version>1.3.3</postgres-socket-factory.version>
[...]
		<dependency>
			<groupId>io.quarkus</groupId>
			<artifactId>quarkus-jdbc-postgresql</artifactId>
		</dependency>
		<dependency>
			<groupId>io.quarkus</groupId>
			<artifactId>quarkus-hibernate-orm-panache</artifactId>
		</dependency>
		<dependency>
			<groupId>com.google.cloud.sql</groupId>
			<artifactId>postgres-socket-factory</artifactId>
			<version>${postgres-socket-factory.version}</version>
		</dependency>
```

Sidenote on deployment?
----------------------------
How to investigate this warning on ´mvn clean package appengine:deploy´?

```
[INFO] Staging the application to: D:\\eclipse\\eclipse-workspace\\code-with-quarkus\\target\\appengine-staging
[INFO] Detected App Engine app.yaml based application.
Okt. 01, 2021 8:08:38 AM com.google.cloud.tools.appengine.operations.AppYamlProjectStaging copyArtifactJarClasspath
WARNING: Could not copy 'Class-Path' jar: D:\\eclipse\\eclipse-workspace\\code-with-quarkus\\target referenced in MANIFEST.MF
```

Just a sidenote as deployment with `gcloud app deploy target/code-with-quarkus-1.0.0-SNAPSHOT-runner.jar` gives no WARNINFS and has same effects.

Alternative with mysql is functioning
=====================================
I've tried an alternative with mysql, which is functioning in the same MCVE and another testing project which I have set up.

pom.xml
```
		<dependency>
			<groupId>io.quarkus</groupId>
			<artifactId>quarkus-jdbc-mysql</artifactId>
		</dependency>
		<dependency>
			<groupId>com.google.cloud.sql</groupId>
			<artifactId>mysql-socket-factory-connector-j-8</artifactId>
			<version>1.3.3</version>
		</dependency>
```

application.properties
```
# https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory/blob/main/docs/jdbc-mysql.md
quarkus.datasource.db-kind=other 
quarkus.datasource.jdbc.url=jdbc:mysql:///quarkus 
quarkus.datasource.jdbc.driver=com.mysql.cj.jdbc.Driver
quarkus.datasource.username=root
quarkus.datasource.password=quarkus
quarkus.datasource.jdbc.additional-jdbc-properties.cloudSqlInstance=addlogic-foodiefnf-1:europe-west3:quarkusmysql
quarkus.datasource.jdbc.additional-jdbc-properties.socketFactory=com.google.cloud.sql.mysql.SocketFactory
quarkus.hibernate-orm.dialect=org.hibernate.dialect.MySQL8Dialect
```

***So this makes me more curious why it is not working with PostgreSQL.***


### How to Reproduce?

An MCVE reproducer project can be found at 
`git@gitlab.com:addlogic/code-with-quarkus.git#`

See README for reproduction steps.

### Output of `uname -a` or `ver`

CYGWIN_NT-10.0 levante2b 3.2.0(0.340/5/3) 2021-03-29 08:42 x86_64 Cygwin

### Output of `java -version`

$ java -version java version "11.0.11" 2021-04-20 LTS Java(TM) SE Runtime Environment 18.9 (build 11.0.11+9-LTS-194) Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.11+9-LTS-194, mixed mode)

### GraalVM version (if different from Java)

_No response_

### Quarkus version or git rev

2.2.3.Final

### Build tool (ie. output of `mvnw --version` or `gradlew --version`)

apache-maven-3.8.1

### Additional information

_No response_

Changed files:
extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DataSourceRuntimeConfig.java
core/runtime/src/main/java/io/quarkus/runtime/configuration/TrimmedStringConverter.java
extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/HibernateOrmRuntimeConfigPersistenceUnit.java
core/runtime/src/main/java/io/quarkus/runtime/configuration/CharsetConverter.java
extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmConfigPersistenceUnit.java
extensions/agroal/runtime/src/main/java/io/quarkus/agroal/runtime/DataSourceJdbcBuildTimeConfig.java

diff --git a/core/runtime/src/main/java/io/quarkus/runtime/configuration/CharsetConverter.java b/core/runtime/src/main/java/io/quarkus/runtime/configuration/CharsetConverter.java
index 33e03cd274b..cd1436fca8e 100644
--- a/core/runtime/src/main/java/io/quarkus/runtime/configuration/CharsetConverter.java
+++ b/core/runtime/src/main/java/io/quarkus/runtime/configuration/CharsetConverter.java
@@ -19,10 +19,20 @@ public class CharsetConverter implements Converter<Charset>, Serializable {
 
     @Override
     public Charset convert(String value) {
+        if (value == null) {
+            return null;
+        }
+
+        String trimmedCharset = value.trim();
+
+        if (trimmedCharset.isEmpty()) {
+            return null;
+        }
+
         try {
-            return Charset.forName(value);
+            return Charset.forName(trimmedCharset);
         } catch (Exception e) {
-            throw new IllegalArgumentException("Unable to create Charset from: '" + value + "'", e);
+            throw new IllegalArgumentException("Unable to create Charset from: '" + trimmedCharset + "'", e);
         }
     }
 }
diff --git a/core/runtime/src/main/java/io/quarkus/runtime/configuration/TrimmedStringConverter.java b/core/runtime/src/main/java/io/quarkus/runtime/configuration/TrimmedStringConverter.java
index 4588db6b50e..f0f8eabbedf 100644
--- a/core/runtime/src/main/java/io/quarkus/runtime/configuration/TrimmedStringConverter.java
+++ b/core/runtime/src/main/java/io/quarkus/runtime/configuration/TrimmedStringConverter.java
@@ -10,8 +10,15 @@ public TrimmedStringConverter() {
     @Override
     public String convert(String s) {
         if (s == null) {
-            return s;
+            return null;
         }
-        return s.trim();
+
+        String trimmedString = s.trim();
+
+        if (trimmedString.isEmpty()) {
+            return null;
+        }
+
+        return trimmedString;
     }
 }
diff --git a/extensions/agroal/runtime/src/main/java/io/quarkus/agroal/runtime/DataSourceJdbcBuildTimeConfig.java b/extensions/agroal/runtime/src/main/java/io/quarkus/agroal/runtime/DataSourceJdbcBuildTimeConfig.java
index 2b9c324b2a2..6d5e3877ac7 100644
--- a/extensions/agroal/runtime/src/main/java/io/quarkus/agroal/runtime/DataSourceJdbcBuildTimeConfig.java
+++ b/extensions/agroal/runtime/src/main/java/io/quarkus/agroal/runtime/DataSourceJdbcBuildTimeConfig.java
@@ -4,6 +4,8 @@
 
 import io.quarkus.runtime.annotations.ConfigGroup;
 import io.quarkus.runtime.annotations.ConfigItem;
+import io.quarkus.runtime.annotations.ConvertWith;
+import io.quarkus.runtime.configuration.TrimmedStringConverter;
 
 @ConfigGroup
 public class DataSourceJdbcBuildTimeConfig {
@@ -18,6 +20,7 @@ public class DataSourceJdbcBuildTimeConfig {
      * The datasource driver class name
      */
     @ConfigItem
+    @ConvertWith(TrimmedStringConverter.class)
     public Optional<String> driver = Optional.empty();
 
     /**
diff --git a/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DataSourceRuntimeConfig.java b/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DataSourceRuntimeConfig.java
index 82c9f351e8c..d22a84034e5 100644
--- a/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DataSourceRuntimeConfig.java
+++ b/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DataSourceRuntimeConfig.java
@@ -4,6 +4,8 @@
 
 import io.quarkus.runtime.annotations.ConfigGroup;
 import io.quarkus.runtime.annotations.ConfigItem;
+import io.quarkus.runtime.annotations.ConvertWith;
+import io.quarkus.runtime.configuration.TrimmedStringConverter;
 
 @ConfigGroup
 public class DataSourceRuntimeConfig {
@@ -24,6 +26,7 @@ public class DataSourceRuntimeConfig {
      * The credentials provider name
      */
     @ConfigItem
+    @ConvertWith(TrimmedStringConverter.class)
     public Optional<String> credentialsProvider = Optional.empty();
 
     /**
@@ -35,5 +38,6 @@ public class DataSourceRuntimeConfig {
      * For Vault it is: vault-credentials-provider. Not necessary if there is only one credentials provider available.
      */
     @ConfigItem
+    @ConvertWith(TrimmedStringConverter.class)
     public Optional<String> credentialsProviderName = Optional.empty();
 }
diff --git a/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmConfigPersistenceUnit.java b/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmConfigPersistenceUnit.java
index b7e4ad913de..c0018f9e2ab 100644
--- a/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmConfigPersistenceUnit.java
+++ b/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmConfigPersistenceUnit.java
@@ -14,6 +14,8 @@
 import io.quarkus.runtime.annotations.ConfigDocSection;
 import io.quarkus.runtime.annotations.ConfigGroup;
 import io.quarkus.runtime.annotations.ConfigItem;
+import io.quarkus.runtime.annotations.ConvertWith;
+import io.quarkus.runtime.configuration.TrimmedStringConverter;
 
 @ConfigGroup
 public class HibernateOrmConfigPersistenceUnit {
@@ -23,11 +25,13 @@ public class HibernateOrmConfigPersistenceUnit {
      * <p>
      * If undefined, it will use the default datasource.
      */
+    @ConvertWith(TrimmedStringConverter.class)
     public Optional<String> datasource;
 
     /**
      * The packages in which the entities affected to this persistence unit are located.
      */
+    @ConvertWith(TrimmedStringConverter.class)
     public Optional<Set<String>> packages;
 
     /**
@@ -71,6 +75,7 @@ public class HibernateOrmConfigPersistenceUnit {
      */
     // @formatter:on
     @ConfigItem(defaultValueDocumentation = "import.sql in DEV, TEST ; no-file otherwise")
+    @ConvertWith(TrimmedStringConverter.class)
     public Optional<List<String>> sqlLoadScript;
 
     /**
@@ -103,6 +108,7 @@ public class HibernateOrmConfigPersistenceUnit {
      * Class name of the Hibernate PhysicalNamingStrategy implementation
      */
     @ConfigItem
+    @ConvertWith(TrimmedStringConverter.class)
     public Optional<String> physicalNamingStrategy;
 
     /**
@@ -111,6 +117,7 @@ public class HibernateOrmConfigPersistenceUnit {
      * Class name of the Hibernate ImplicitNamingStrategy implementation
      */
     @ConfigItem
+    @ConvertWith(TrimmedStringConverter.class)
     public Optional<String> implicitNamingStrategy;
 
     /**
@@ -130,6 +137,7 @@ public class HibernateOrmConfigPersistenceUnit {
      * @asciidoclet
      */
     @ConfigItem
+    @ConvertWith(TrimmedStringConverter.class)
     public Optional<String> metadataBuilderContributor;
 
     /**
@@ -139,6 +147,7 @@ public class HibernateOrmConfigPersistenceUnit {
      * Pass `no-file` to force Hibernate ORM to ignore `META-INF/orm.xml`.
      */
     @ConfigItem(defaultValueDocumentation = "META-INF/orm.xml if it exists; no-file otherwise")
+    @ConvertWith(TrimmedStringConverter.class)
     public Optional<Set<String>> mappingFiles;
 
     /**
@@ -201,6 +210,7 @@ public class HibernateOrmConfigPersistenceUnit {
      * @asciidoclet
      */
     @ConfigItem
+    @ConvertWith(TrimmedStringConverter.class)
     public Optional<String> multitenant;
 
     /**
@@ -208,6 +218,7 @@ public class HibernateOrmConfigPersistenceUnit {
      * if not set.
      */
     @ConfigItem
+    @ConvertWith(TrimmedStringConverter.class)
     public Optional<String> multitenantSchemaDatasource;
 
     /**
@@ -259,6 +270,7 @@ public static class HibernateOrmConfigPersistenceUnitDialect {
         // TODO should it be dialects
         //TODO should it be shortcuts like "postgresql" "h2" etc
         @ConfigItem(name = ConfigItem.PARENT)
+        @ConvertWith(TrimmedStringConverter.class)
         public Optional<String> dialect;
 
         /**
@@ -269,6 +281,7 @@ public static class HibernateOrmConfigPersistenceUnitDialect {
          * @asciidoclet
          */
         @ConfigItem
+        @ConvertWith(TrimmedStringConverter.class)
         public Optional<String> storageEngine;
 
         public boolean isAnyPropertySet() {
@@ -342,6 +355,7 @@ public static class HibernateOrmConfigPersistenceUnitJdbc {
          * The time zone pushed to the JDBC driver.
          */
         @ConfigItem
+        @ConvertWith(TrimmedStringConverter.class)
         public Optional<String> timezone;
 
         /**
diff --git a/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/HibernateOrmRuntimeConfigPersistenceUnit.java b/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/HibernateOrmRuntimeConfigPersistenceUnit.java
index b3676ba8270..98bb49330d9 100644
--- a/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/HibernateOrmRuntimeConfigPersistenceUnit.java
+++ b/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/HibernateOrmRuntimeConfigPersistenceUnit.java
@@ -5,6 +5,8 @@
 import io.quarkus.runtime.annotations.ConfigDocSection;
 import io.quarkus.runtime.annotations.ConfigGroup;
 import io.quarkus.runtime.annotations.ConfigItem;
+import io.quarkus.runtime.annotations.ConvertWith;
+import io.quarkus.runtime.configuration.TrimmedStringConverter;
 
 @ConfigGroup
 public class HibernateOrmRuntimeConfigPersistenceUnit {
@@ -49,12 +51,14 @@ public static class HibernateOrmConfigPersistenceUnitDatabase {
          * The default catalog to use for the database objects.
          */
         @ConfigItem
+        @ConvertWith(TrimmedStringConverter.class)
         public Optional<String> defaultCatalog;
 
         /**
          * The default schema to use for the database objects.
          */
         @ConfigItem
+        @ConvertWith(TrimmedStringConverter.class)
         public Optional<String> defaultSchema;
 
         public boolean isAnyPropertySet() {
@@ -92,6 +96,7 @@ public static class HibernateOrmConfigPersistenceUnitDatabaseGeneration {
          * Accepted values: `none`, `create`, `drop-and-create`, `drop`, `update`, `validate`.
          */
         @ConfigItem(name = ConfigItem.PARENT, defaultValue = "none")
+        @ConvertWith(TrimmedStringConverter.class)
         public String generation = "none";
 
         /**
@@ -122,18 +127,21 @@ public static class HibernateOrmConfigPersistenceUnitScriptGeneration {
          * Accepted values: `none`, `create`, `drop-and-create`, `drop`, `update`, `validate`.
          */
         @ConfigItem(name = ConfigItem.PARENT, defaultValue = "none")
+        @ConvertWith(TrimmedStringConverter.class)
         public String generation = "none";
 
         /**
          * Filename or URL where the database create DDL file should be generated.
          */
         @ConfigItem
+        @ConvertWith(TrimmedStringConverter.class)
         public Optional<String> createTarget = Optional.empty();
 
         /**
          * Filename or URL where the database drop DDL file should be generated.
          */
         @ConfigItem
+        @ConvertWith(TrimmedStringConverter.class)
         public Optional<String> dropTarget = Optional.empty();
 
         public boolean isAnyPropertySet() {