You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2022/04/26 16:47:24 UTC

[isis] branch master updated: ISIS-3027: improved warning message for non-eagerly introspected types

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

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/master by this push:
     new dd3b479585 ISIS-3027: improved warning message for non-eagerly introspected types
dd3b479585 is described below

commit dd3b4795859ec6c0ffdb1f7f551039bab5b9b331
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Apr 26 18:47:18 2022 +0200

    ISIS-3027: improved warning message for non-eagerly introspected types
    
    - also improves logging of which persistence layer we are actually on
---
 .../progmodel/ProgrammingModelConstants.java       | 10 +++++
 .../specloader/SpecificationLoaderDefault.java     | 51 ++++++++--------------
 ...ficationLoaderDefault_debug.java => _Util.java} | 35 +++++++++++----
 3 files changed, 55 insertions(+), 41 deletions(-)

diff --git a/core/config/src/main/java/org/apache/isis/core/config/progmodel/ProgrammingModelConstants.java b/core/config/src/main/java/org/apache/isis/core/config/progmodel/ProgrammingModelConstants.java
index a0fbed54ca..c1f2b6fd9b 100644
--- a/core/config/src/main/java/org/apache/isis/core/config/progmodel/ProgrammingModelConstants.java
+++ b/core/config/src/main/java/org/apache/isis/core/config/progmodel/ProgrammingModelConstants.java
@@ -452,6 +452,16 @@ public final class ProgrammingModelConstants {
                 + "Spring supports various naming strategies @Named(...) being one of them, "
                 + "where eg. @Named(\"CustomerService\") is considered invalid, "
                 + "whereas @Named(\"sales.CustomerService\") is valid."),
+        TYPE_NOT_EAGERLY_DISCOVERED("The metamodel is configured for FULL introspection mode, "
+                + "yet missed ${type} of sort ${beanSort} during application start. " +
+                "This happens when type ${type} is not eagerly discovered by the metamodel introspection, "
+                + "which (initially) only considers compile-time types via reflection. "
+                + "Run-time types, "
+                + "not explicitly referenced to be included with Spring's class discovery mechanism, "
+                + "might slip this process. "
+                + "Consider importing type ${type} with Spring's @Import annotation. "
+                + "Types of sort VALUE should instead register a ValueSemanticsProvider with Spring, "
+                + "to be properly understood by the framework."),
         ;
         private final String template;
         public String getMessage(final Identifier featureIdentifier) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java
index d41a73b2b7..d445b8f163 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java
@@ -20,6 +20,7 @@ package org.apache.isis.core.metamodel.specloader;
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
@@ -60,6 +61,7 @@ import org.apache.isis.core.config.beans.IsisBeanTypeClassifier;
 import org.apache.isis.core.config.beans.IsisBeanTypeRegistry;
 import org.apache.isis.core.config.environment.IsisSystemEnvironment;
 import org.apache.isis.core.config.metamodel.specloader.IntrospectionMode;
+import org.apache.isis.core.config.progmodel.ProgrammingModelConstants;
 import org.apache.isis.core.metamodel.commons.ClassUtil;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facetapi.Facet;
@@ -277,8 +279,9 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
         });
 
         //XXX[ISIS-2382] when parallel introspecting, make sure we have the mixins before their holders
+        // (observation by experiment, no real understanding as to why)
 
-        SpecificationLoaderDefault_debug.logBefore(log, cache, knownSpecs);
+        _Util.logBefore(log, cache, knownSpecs);
 
         log.info(" - introspecting {} type hierarchies", knownSpecs.size());
         introspect(Can.ofCollection(knownSpecs), IntrospectionState.TYPE_INTROSPECTED);
@@ -289,20 +292,20 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
         log.info(" - introspecting {} mixins", isisBeanTypeRegistry.getMixinTypes().size());
         introspect(Can.ofCollection(mixinSpecs), IntrospectionState.FULLY_INTROSPECTED);
 
-        log.info(" - introspecting {} managed beans contributing (domain services)", isisBeanTypeRegistry.getManagedBeansContributing().size());
-//        log.info(" - introspecting {}/{} entities (JDO/JPA)",
-//                isisBeanTypeRegistry.getEntityTypesJdo().size(),
-//                isisBeanTypeRegistry.getEntityTypesJpa().size());
+        log.info(" - introspecting {} managed beans contributing (domain services)",
+                isisBeanTypeRegistry.getManagedBeansContributing().size());
+
+        log.info(" - introspecting {} entities ({})",
+                isisBeanTypeRegistry.getEntityTypes().size(),
+                _Util.persistenceLayerName());
 
-        log.info(" - introspecting {} entities (JDO+JPA)",
-                isisBeanTypeRegistry.getEntityTypes().size());
         log.info(" - introspecting {} view models", isisBeanTypeRegistry.getViewModelTypes().size());
 
         serviceRegistry.lookupServiceElseFail(MenuBarsService.class).menuBars();
 
         introspect(Can.ofCollection(domainObjectSpecs), IntrospectionState.FULLY_INTROSPECTED);
 
-        SpecificationLoaderDefault_debug.logAfter(log, cache, knownSpecs);
+        _Util.logAfter(log, cache, knownSpecs);
 
         if(isFullIntrospect()) {
             val snapshot = cache.snapshotSpecs();
@@ -564,31 +567,15 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
         if(isMetamodelFullyIntrospected()
                 && isisConfiguration.getCore().getMetaModel().getIntrospector().isLockAfterFullIntrospection()) {
 
-            val sort = isisBeanTypeClassifier
-                    .classify(cls)
-                    .getBeanSort();
-
-//          ISIS-2256:
-//            throw _Exceptions.illegalState(
-//                    "Cannot introspect class '%s' of sort %s, because the metamodel has been fully introspected and is now locked. " +
-//                    "One reason this can happen is if you are attempting to invoke an action through the WrapperFactory " +
-//                    "on a service class incorrectly annotated with Spring's @Service annotation instead of " +
-//                    "@DomainService.",
-//                    cls.getName(), sort);
-
-            log.warn("Missed class '{}' when the metamodel was fully introspected.", cls.getName());
+            val warningMessage = ProgrammingModelConstants.Validation.TYPE_NOT_EAGERLY_DISCOVERED
+                .getMessage(Map.of(
+                        "type", cls.getName(),
+                        "beanSort", isisBeanTypeClassifier
+                            .classify(cls)
+                            .getBeanSort()
+                            .name()));
 
-            if(sort.isValue()) {
-                return; // opinionated: just relax when value
-            }
-
-            if(sort.isToBeIntrospected()) {
-                log.warn("Introspecting class '{}' of sort {}, after the metamodel had been fully introspected and is now locked. " +
-                      "One reason this can happen is if you are attempting to invoke an action through the WrapperFactory " +
-                      "on a service class incorrectly annotated with Spring's @Service annotation instead of " +
-                      "@DomainService.",
-                        cls.getName(), sort);
-            }
+            log.warn(warningMessage);
         }
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault_debug.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/_Util.java
similarity index 69%
rename from core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault_debug.java
rename to core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/_Util.java
index a951aa5747..1dcc5b537c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault_debug.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/_Util.java
@@ -24,16 +24,19 @@ import java.util.stream.Collectors;
 
 import org.apache.logging.log4j.Logger;
 
+import org.apache.isis.core.config.beans.IsisBeanTypeClassifier;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 
 import lombok.val;
+import lombok.experimental.UtilityClass;
 
-final class SpecificationLoaderDefault_debug {
+@UtilityClass
+final class _Util {
 
-    static void logBefore(
-            Logger log,
-            SpecificationCache<ObjectSpecification> cache,
-            List<? extends ObjectSpecification> scanned) {
+    void logBefore(
+            final Logger log,
+            final SpecificationCache<ObjectSpecification> cache,
+            final List<? extends ObjectSpecification> scanned) {
 
         if(!log.isDebugEnabled()) {
             return;
@@ -57,10 +60,10 @@ final class SpecificationLoaderDefault_debug {
                 registryNotCached.size(), cachedNotRegistry.size()));
     }
 
-    static void logAfter(
-            Logger log,
-            SpecificationCache<ObjectSpecification> cache,
-            Collection<? extends ObjectSpecification> scanned) {
+    void logAfter(
+            final Logger log,
+            final SpecificationCache<ObjectSpecification> cache,
+            final Collection<? extends ObjectSpecification> scanned) {
 
         if(!log.isDebugEnabled()) {
             return;
@@ -76,4 +79,18 @@ final class SpecificationLoaderDefault_debug {
                 cached.size(), cachedAfterNotBefore.size()));
     }
 
+    /**
+     * Returns either 'JDO' or 'JPA' based on what {@link IsisBeanTypeClassifier} we find
+     * registered with <i>Spring</i>.
+     * Alternative implementations could be considered, however this works for now.
+     */
+    String persistenceLayerName() {
+        return IsisBeanTypeClassifier.get().stream()
+            .map(IsisBeanTypeClassifier::getClass)
+            .map(Class::getSimpleName)
+            .anyMatch(classifierName->classifierName.startsWith("Jdo"))
+            ? "JDO "
+            : "JPA";
+    }
+
 }