Skip to content

Commit 7a42453

Browse files
marko-bekhtagsmet
authored andcommitted
Include the reasons why the check breaks the start
1 parent b25c7df commit 7a42453

File tree

2 files changed

+43
-26
lines changed

2 files changed

+43
-26
lines changed

extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/customized/BuiltinFormatMapperBehaviour.java

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.quarkus.hibernate.orm.runtime.customized;
22

3+
import java.util.List;
34
import java.util.Locale;
45
import java.util.concurrent.atomic.AtomicBoolean;
56

@@ -19,7 +20,7 @@ public enum BuiltinFormatMapperBehaviour {
1920
*/
2021
IGNORE {
2122
@Override
22-
protected void action(String puName, String type) {
23+
protected void action(String puName, String type, List<String> causes) {
2324
}
2425
},
2526
/**
@@ -28,25 +29,25 @@ protected void action(String puName, String type) {
2829
*/
2930
WARN {
3031
@Override
31-
protected void action(String puName, String type) {
32-
LOGGER.warn(message(puName, type));
32+
protected void action(String puName, String type, List<String> causes) {
33+
LOGGER.warn(message(puName, type, causes));
3334
}
3435
},
3536
/**
3637
* Currently the default one. If there is no user provided format mapper, a Quarkus preconfigured one will fail at runtime.
3738
*/
3839
FAIL {
3940
@Override
40-
protected void action(String puName, String type) {
41-
throw new IllegalStateException(message(puName, type));
41+
protected void action(String puName, String type, List<String> causes) {
42+
throw new IllegalStateException(message(puName, type, causes));
4243
}
4344
};
4445

4546
private static final Logger LOGGER = Logger.getLogger(BuiltinFormatMapperBehaviour.class);
4647
private static final String TYPE_JSON = "JSON";
4748
private static final String TYPE_XML = "XML";
4849

49-
private static String message(String puName, String type) {
50+
private static String message(String puName, String type, List<String> causes) {
5051
return String.format(Locale.ROOT,
5152
"Persistence unit [%1$s] uses Quarkus' main formatting facilities for %2$s columns in the database. "
5253
+ "\nAs these facilities are primarily meant for REST endpoints, and they might have been customized for such use, "
@@ -58,6 +59,8 @@ private static String message(String puName, String type) {
5859
+ " and @PersistenceUnitExtension"
5960
+ (PersistenceUnitUtil.isDefaultPersistenceUnit(puName) ? "" : "(\"%1$s\")")
6061
+ " to address your database serialization/deserialization needs."
62+
+ "\nThe reasons why the check was triggered are: \n\t-"
63+
+ String.join("\n\t-", causes)
6164
+ "\nSee the migration guide for more details and how to proceed.",
6265
puName, type);
6366
}
@@ -94,8 +97,11 @@ public static boolean hasXmlProperties(MetadataImplementor metadata) {
9497

9598
public void jsonApply(MetadataImplementor metadata, String puName, ArcContainer container,
9699
JsonFormatterCustomizationCheck check) {
97-
if (hasJsonProperties(metadata) && check.test(container)) {
98-
action(puName, TYPE_JSON);
100+
if (hasJsonProperties(metadata)) {
101+
List<String> causes = check.apply(container);
102+
if (!causes.isEmpty()) {
103+
action(puName, TYPE_JSON, causes);
104+
}
99105
}
100106
}
101107

@@ -110,9 +116,10 @@ public void xmlApply(MetadataImplementor metadata, String puName) {
110116
// Let's fail and tell the user to migrate their data to the new format and before that is done: use a delegate to org.hibernate.type.format.jaxb.JaxbXmlFormatMapper()
111117
// using a legacy format:
112118
if (hasXmlProperties(metadata)) {
113-
action(puName, TYPE_XML);
119+
action(puName, TYPE_XML,
120+
List.of("The XML format mapper uses the legacy format. It is not compatible with the new default one."));
114121
}
115122
}
116123

117-
protected abstract void action(String puName, String type);
124+
protected abstract void action(String puName, String type, List<String> causes);
118125
}

extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/customized/JsonFormatterCustomizationCheck.java

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package io.quarkus.hibernate.orm.runtime.customized;
22

3+
import java.util.ArrayList;
4+
import java.util.List;
35
import java.util.Map;
46
import java.util.Set;
5-
import java.util.function.Predicate;
7+
import java.util.function.Function;
68

79
import jakarta.enterprise.inject.Instance;
810
import jakarta.json.bind.Jsonb;
@@ -20,9 +22,9 @@
2022
* Test whether the underlying Jackson Object Mapper / JSON-B used to create the "built-in" format mapper
2123
* were modified and cannot be safely replaced by the Hibernate ORM's default ones.
2224
*/
23-
public interface JsonFormatterCustomizationCheck extends Predicate<ArcContainer> {
25+
public interface JsonFormatterCustomizationCheck extends Function<ArcContainer, List<String>> {
2426
@Override
25-
boolean test(ArcContainer container);
27+
List<String> apply(ArcContainer container);
2628

2729
static JsonFormatterCustomizationCheck jsonFormatterCustomizationCheckSupplier(boolean required, boolean isJackson) {
2830
if (!required) {
@@ -37,22 +39,24 @@ static JsonFormatterCustomizationCheck jsonFormatterCustomizationCheckSupplier(b
3739

3840
class NotModifiedJsonFormatterCustomizationCheck implements JsonFormatterCustomizationCheck {
3941
@Override
40-
public boolean test(ArcContainer container) {
41-
return false;
42+
public List<String> apply(ArcContainer container) {
43+
return List.of();
4244
}
4345
}
4446

4547
class JacksonJsonFormatterCustomizationCheck implements JsonFormatterCustomizationCheck {
4648
@Override
47-
public boolean test(ArcContainer container) {
49+
public List<String> apply(ArcContainer container) {
4850
InstanceHandle<ObjectMapper> objectMapperInstance = container.instance(ObjectMapper.class);
4951
if (!objectMapperInstance.isAvailable()) {
5052
// We have no mapper so it wasn't modified, and we've probably used the JSONB instead.
51-
return false;
53+
return List.of();
5254
}
55+
List<String> causes = new ArrayList<>();
5356
if (!objectMapperInstance.getBean().isDefaultBean()) {
5457
// A bean producer was used and the ObjectMapper is a user custom bean...
55-
return true;
58+
causes.add(
59+
"ObjectMapper instance is not the Quarkus default one. A bean producer was likely used to replace it.");
5660
}
5761

5862
Instance<ObjectMapperCustomizer> customizers = container.select(ObjectMapperCustomizer.class);
@@ -70,7 +74,8 @@ public boolean test(ArcContainer container) {
7074
continue;
7175
}
7276
// ObjectMapper was potentially customized
73-
return true;
77+
causes.add("Detected '" + handle.getBean().getBeanClass().getName() + "' bean registered. "
78+
+ "It may have customized the ObjectMapper in a way not compatible with the default one.");
7479
}
7580
}
7681

@@ -87,26 +92,30 @@ public boolean test(ArcContainer container) {
8792
String okValue = expectedDefaults.get(propertyName);
8893
if (okValue != null && !okValue
8994
.equalsIgnoreCase(ConfigProvider.getConfig().getConfigValue(propertyName).getRawValue())) {
90-
return true;
95+
causes.add("Detected '" + propertyName + "' property set to '"
96+
+ ConfigProvider.getConfig().getConfigValue(propertyName).getRawValue() + "'. "
97+
+ "For ObjectMapper being compatible with the clean, default one the expected value is: '"
98+
+ okValue + "'.");
9199
}
92100
}
93101
}
94102

95-
return false;
103+
return causes;
96104
}
97105
}
98106

99107
class JsonbJsonFormatterCustomizationCheck implements JsonFormatterCustomizationCheck {
100108
@Override
101-
public boolean test(ArcContainer container) {
109+
public List<String> apply(ArcContainer container) {
102110
InstanceHandle<Jsonb> jsonbInstance = container.instance(Jsonb.class);
103111
if (!jsonbInstance.isAvailable()) {
104112
// We have no JSON-B bean so it wasn't modified.
105-
return false;
113+
return List.of();
106114
}
115+
List<String> causes = new ArrayList<>();
107116
if (!jsonbInstance.getBean().isDefaultBean()) {
108117
// A bean producer was used and the JSON-B is a user custom bean...
109-
return true;
118+
causes.add("Jsonb instance is not the Quarkus default one. A bean producer was likely used to replace it.");
110119
}
111120

112121
Instance<JsonbConfigCustomizer> customizers = container.select(JsonbConfigCustomizer.class);
@@ -120,11 +129,12 @@ public boolean test(ArcContainer container) {
120129
}
121130

122131
// JSON-B was potentially customized
123-
return true;
132+
causes.add("Detected '" + handle.getBean().getBeanClass().getName() + "' bean registered. "
133+
+ "It may have customized the Jsonb in a way not compatible with the default one.");
124134
}
125135

126136
// JSON-B does not have the config properties so nothing else to check..
127-
return false;
137+
return causes;
128138
}
129139
}
130140
}

0 commit comments

Comments
 (0)