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 2021/04/15 13:20:35 UTC

[isis] branch master updated: ISIS-2569: do not use SpecLoader#loadSpecification(Class) - (4)

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 211eaf9  ISIS-2569: do not use SpecLoader#loadSpecification(Class) - (4)
211eaf9 is described below

commit 211eaf98ec889fcfbb731b2cf58d33d71eb92ba2
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Apr 15 15:19:06 2021 +0200

    ISIS-2569: do not use SpecLoader#loadSpecification(Class) - (4)
    
    ... when outside the scope of initial spec loading (its optimized for
    initial loading, skips introspecting members)
    
    also polishing BookmarkService
---
 .../modules/ROOT/pages/2021/2.0.0-M6/mignotes.adoc |  4 ++
 .../applib/jaxb/PersistentEntitiesAdapter.java     |  2 +-
 .../isis/applib/jaxb/PersistentEntityAdapter.java  |  2 +-
 .../mixins/metamodel/Object_objectIdentifier.java  |  2 +-
 .../applib/mixins/metamodel/Object_objectType.java |  2 +-
 .../applib/mixins/rest/Object_openRestApi.java     |  2 +-
 .../applib/services/bookmark/BookmarkService.java  | 63 +++++++++++-----------
 .../isis/applib/util/schema/CommonDtoUtils.java    |  2 +-
 .../bookmarks/BookmarkServiceDefault.java          | 62 +++++++++++++--------
 .../wrapper/WrapperFactoryDefault.java             |  2 +-
 .../dom/types/isis/markups/jdo/IsisMarkupJdo.java  |  2 +-
 .../isisext/asciidocs/jdo/IsisAsciiDocJdo.java     |  2 +-
 .../isisext/markdowns/jdo/IsisMarkdownJdo.java     |  2 +-
 .../impl/mixins/Object_recentCommands.java         | 13 +++--
 .../commandlog/impl/mixins/T_recent.java           |  9 ++--
 .../excel/applib/dom/util/CellMarshaller.java      |  2 +-
 .../wicket/viewer/mixins/Object_clearHints.java    |  2 +-
 17 files changed, 98 insertions(+), 77 deletions(-)

diff --git a/antora/components/relnotes/modules/ROOT/pages/2021/2.0.0-M6/mignotes.adoc b/antora/components/relnotes/modules/ROOT/pages/2021/2.0.0-M6/mignotes.adoc
index d171f82..401fde0 100644
--- a/antora/components/relnotes/modules/ROOT/pages/2021/2.0.0-M6/mignotes.adoc
+++ b/antora/components/relnotes/modules/ROOT/pages/2021/2.0.0-M6/mignotes.adoc
@@ -33,5 +33,9 @@ there is no counterpart for _Collection_
 
 |===
 
+== Other Changes
+
 Module `IsisModuleExtModelAnnotation` was removed and is no longer required.
 
+Service `BookmarkService` has been improved, such that its methods return `Optional<?>` instead of nullable objects. 
+
diff --git a/api/applib/src/main/java/org/apache/isis/applib/jaxb/PersistentEntitiesAdapter.java b/api/applib/src/main/java/org/apache/isis/applib/jaxb/PersistentEntitiesAdapter.java
index 018171d..d08557a 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/jaxb/PersistentEntitiesAdapter.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/jaxb/PersistentEntitiesAdapter.java
@@ -60,7 +60,7 @@ public class PersistentEntitiesAdapter extends XmlAdapter<OidsDto, List<Object>>
         }
         val oidsDto = new OidsDto();
         for (val domainObject : domainObjects) {
-            val bookmark = getBookmarkService().bookmarkForElseThrow(domainObject);
+            val bookmark = getBookmarkService().bookmarkForElseFail(domainObject);
             oidsDto.getOid().add(bookmark.toOidDto());
         }
         return oidsDto;
diff --git a/api/applib/src/main/java/org/apache/isis/applib/jaxb/PersistentEntityAdapter.java b/api/applib/src/main/java/org/apache/isis/applib/jaxb/PersistentEntityAdapter.java
index 49905fc..3054ff8 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/jaxb/PersistentEntityAdapter.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/jaxb/PersistentEntityAdapter.java
@@ -45,7 +45,7 @@ public class PersistentEntityAdapter extends XmlAdapter<OidDto, Object> {
         if(domainObject == null) {
             return null;
         }
-        val bookmark = bookmarkService.bookmarkForElseThrow(domainObject);
+        val bookmark = bookmarkService.bookmarkForElseFail(domainObject);
         return bookmark.toOidDto();
     }
 
diff --git a/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_objectIdentifier.java b/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_objectIdentifier.java
index a902faa..fb5a0a6 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_objectIdentifier.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_objectIdentifier.java
@@ -68,7 +68,7 @@ public class Object_objectIdentifier {
     extends org.apache.isis.applib.IsisModuleApplib.ActionDomainEvent<Object_objectIdentifier> {}
 
     public String prop() {
-        val bookmark = bookmarkService.bookmarkForElseThrow(this.holder);
+        val bookmark = bookmarkService.bookmarkForElseFail(this.holder);
         val sort = mmService.sortOf(bookmark, MetaModelService.Mode.RELAXED);
         if(!sort.isEntity()) {
             return shortend(bookmark.getIdentifier());
diff --git a/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_objectType.java b/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_objectType.java
index c4c85d3..fb1954e 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_objectType.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_objectType.java
@@ -64,7 +64,7 @@ public class Object_objectType {
     extends org.apache.isis.applib.IsisModuleApplib.ActionDomainEvent<Object_objectType> {}
 
     public String prop() {
-        val bookmark = bookmarkService.bookmarkForElseThrow(this.holder);
+        val bookmark = bookmarkService.bookmarkForElseFail(this.holder);
         return bookmark.getObjectType();
     }
 
diff --git a/api/applib/src/main/java/org/apache/isis/applib/mixins/rest/Object_openRestApi.java b/api/applib/src/main/java/org/apache/isis/applib/mixins/rest/Object_openRestApi.java
index 8b320bd..c311df0 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/mixins/rest/Object_openRestApi.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/mixins/rest/Object_openRestApi.java
@@ -62,7 +62,7 @@ public class Object_openRestApi {
     private final Object holder;
 
     public LocalResourcePath act() {
-        val bookmark = bookmarkService.bookmarkForElseThrow(holder);
+        val bookmark = bookmarkService.bookmarkForElseFail(holder);
         val objType = bookmark.getObjectType();
         val objId = bookmark.getIdentifier();
 
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/BookmarkService.java b/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/BookmarkService.java
index e18d4cf..467c0f3 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/BookmarkService.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/BookmarkService.java
@@ -18,13 +18,13 @@
  */
 package org.apache.isis.applib.services.bookmark;
 
+import java.util.Optional;
+
 import javax.annotation.Nullable;
 
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 
-import static org.apache.isis.commons.internal.base._With.requires;
-
-import lombok.val;
+import lombok.NonNull;
 
 /**
  * This service provides a serializable 'bookmark' for any entity, and
@@ -35,62 +35,63 @@ import lombok.val;
 public interface BookmarkService {
 
     /**
-     * Returns the {@link Bookmark} for the given domain object.
+     * Optionally returns the {@link Bookmark} for the given domain object, 
+     * based on whether can create a bookmark for it.
      *
      * <p>
-     * <b>Note</b>: Not every domain object is bookmark-able: only entities, view models and services (NOT values or collections)
+     * <b>Note</b>: Not every domain object is bookmark-able: 
+     * only entities, view models and services (NOT values or collections)
      * </p>
      *
      * @param domainObject - domain object (if any) to return a bookmark for
      * @return optionally a {@link Bookmark} representing given {@code domainObject}
      */
-    Bookmark bookmarkFor(@Nullable Object domainObject);
-
-    /**
-     * As per {@link #bookmarkFor(Object)}, but requires that a non-null {@link Bookmark} is returned.
-     *
-     * @param domainObject - that can be bookmarked
-     * @return a (non-null) {@link Bookmark} for the provided domain object.
-     */
-    default Bookmark bookmarkForElseThrow(Object domainObject) {
-
-        requires(domainObject, "domainObject");
-        val bookmark = bookmarkFor(domainObject);
-        if(bookmark!=null) {
-            return bookmark;
-        }
-        throw _Exceptions.illegalArgument(
-                "cannot create bookmark for type %s", domainObject.getClass().getName());
-    }
+    Optional<Bookmark> bookmarkFor(@Nullable Object domainObject);
 
     /**
-     * Utility method that creates a {@link Bookmark} from the constituent parts.
+     * Optionally returns a {@link Bookmark} created from the constituent parts, 
+     * based on whether can create a bookmark from these.
      *
      * @return - {@link Bookmark} for provided class and identifier
      */
-    Bookmark bookmarkFor(Class<?> cls, String identifier);
+    Optional<Bookmark> bookmarkFor(@Nullable Class<?> cls, @Nullable String identifier);
 
     /**
      * @see #lookup(Bookmark)
      *
      * @param bookmarkHolder - from which the {@link Bookmark} is obtained
-     * @return - corresponding domain object
+     * @return - optionally, the corresponding domain object
      */
-    Object lookup(BookmarkHolder bookmarkHolder);
+    Optional<Object> lookup(@Nullable BookmarkHolder bookmarkHolder);
 
     /**
      * Reciprocal of {@link #bookmarkFor(Object)}
      *
      * @param bookmark - representing a domain object
-     * @return - the corresponding domain object
+     * @return - optionally, the corresponding domain object
      */
-    Object lookup(Bookmark bookmark);
+    Optional<Object> lookup(@Nullable Bookmark bookmark);
 
+    // -- SHORTCUTS
+    
     /**
      * As {@link #lookup(Bookmark)}, but down-casting to the specified type.
      */
-    default <T> T lookup(Bookmark bookmark, Class<T> cls) {
-        return cls.cast(lookup(bookmark));
+    default <T> Optional<T> lookup(@Nullable Bookmark bookmark, @NonNull Class<T> cls) {
+        return lookup(bookmark)
+                .map(t->cls.cast(t));
+    }
+    
+    /**
+     * As per {@link #bookmarkFor(Object)}, but requires that a non-null {@link Bookmark} is returned.
+     *
+     * @param domainObject - to be bookmarked
+     * @return a (non-null) {@link Bookmark} for the provided domain object.
+     */
+    default Bookmark bookmarkForElseFail(@Nullable Object domainObject) {
+        return bookmarkFor(domainObject)
+                .orElseThrow(()->_Exceptions.illegalArgument(
+                        "cannot create bookmark for type %s", domainObject.getClass().getName()));
     }
 
 }
diff --git a/api/applib/src/main/java/org/apache/isis/applib/util/schema/CommonDtoUtils.java b/api/applib/src/main/java/org/apache/isis/applib/util/schema/CommonDtoUtils.java
index fb3589c..e0dc4e6 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/util/schema/CommonDtoUtils.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/util/schema/CommonDtoUtils.java
@@ -318,7 +318,7 @@ public final class CommonDtoUtils {
             final Bookmark bookmark = pojo instanceof Bookmark
                     ? (Bookmark) pojo
                     : bookmarkService!=null
-                            ? bookmarkService.bookmarkFor(pojo)
+                            ? bookmarkService.bookmarkFor(pojo).orElse(null)
                             : null;
 
             if (bookmark != null) {
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/bookmarks/BookmarkServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/bookmarks/BookmarkServiceDefault.java
index 856b233..72e41aa 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/bookmarks/BookmarkServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/bookmarks/BookmarkServiceDefault.java
@@ -20,8 +20,10 @@ package org.apache.isis.core.runtimeservices.bookmarks;
 
 import java.io.Serializable;
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 
+import javax.annotation.Nullable;
 import javax.inject.Inject;
 import javax.inject.Named;
 
@@ -38,12 +40,14 @@ import org.apache.isis.applib.services.bookmark.BookmarkHolder;
 import org.apache.isis.applib.services.bookmark.BookmarkService;
 import org.apache.isis.applib.services.wrapper.WrapperFactory;
 import org.apache.isis.commons.internal.base._Casts;
+import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.commons.internal.collections._Sets;
 import org.apache.isis.commons.internal.memento._Mementos.SerializingAdapter;
 import org.apache.isis.core.metamodel.objectmanager.ObjectManager;
 import org.apache.isis.core.metamodel.objectmanager.load.ObjectLoader;
 import org.apache.isis.core.metamodel.spec.ManagedObjects;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 
 import lombok.val;
@@ -63,58 +67,71 @@ public class BookmarkServiceDefault implements BookmarkService, SerializingAdapt
     @Inject private ObjectManager objectManager;
     
     @Override
-    public Object lookup(BookmarkHolder bookmarkHolder) {
+    public Optional<Object> lookup(final @Nullable BookmarkHolder bookmarkHolder) {
+        if(bookmarkHolder == null) {
+            return Optional.empty();
+        }
         val bookmark = bookmarkHolder.bookmark();
         return bookmark != null
                 ? lookup(bookmark)
-                : null;
+                : Optional.empty();
     }
 
     // why would we ever store Service Beans as Bookmarks?
     // - ANSWER: because it might be used by the CommandService to replay a command or exec in the background.
     @Override
-    public Object lookup(Bookmark bookmark) {
+    public Optional<Object> lookup(final @Nullable Bookmark bookmark) {
         if(bookmark == null) {
-            return null;
+            return Optional.empty();
+        }
+        val spec = specificationLoader.specForBookmark(bookmark).orElse(null);
+        if(spec == null) {
+            return Optional.empty();
         }
         try {
-            val spec = specificationLoader.specForBookmark(bookmark).orElse(null);
             val identifier = bookmark.getIdentifier();
             val objectLoadRequest = ObjectLoader.Request.of(spec, identifier);
-            
             val adapter = objectManager.loadObject(objectLoadRequest);
-            
-            return adapter.getPojo();
-            
-        } catch(ObjectNotFoundException ex) {
-            return null;
+            return Optional.ofNullable(adapter.getPojo());
+        } catch(ObjectNotFoundException ex) {   
+            return Optional.empty();
         }
     }
 
     @Override
-    public Bookmark bookmarkFor(final Object domainObject) {
+    public Optional<Bookmark> bookmarkFor(final @Nullable Object domainObject) {
         if(domainObject == null) {
-            return null;
+            return Optional.empty();
         }
         val adapter = objectManager.adapt(unwrapped(domainObject)); 
         if(!ManagedObjects.isIdentifiable(adapter)){
             // eg values cannot be bookmarked
-            return null;
+            return Optional.empty();
         }
-        return objectManager.identifyObject(adapter)
-                .asBookmark();
+        return Optional.of(
+                objectManager.identifyObject(adapter)
+                .asBookmark());
     }
 
     private Object unwrapped(Object domainObject) {
-        return wrapperFactory != null ? wrapperFactory.unwrap(domainObject) : domainObject;
+        return wrapperFactory != null 
+                ? wrapperFactory.unwrap(domainObject)
+                : domainObject;
     }
 
 
     @Override
-    public Bookmark bookmarkFor(Class<?> cls, String identifier) {
-        val spec = specificationLoader.loadSpecification(cls);
-        val objectType = spec.getLogicalTypeName();
-        return Bookmark.of(objectType, identifier);
+    public Optional<Bookmark> bookmarkFor(
+            final @Nullable Class<?> cls, 
+            final @Nullable String identifier) {
+
+        if(_Strings.isNullOrEmpty(identifier)
+                || cls==null) {
+            return Optional.empty();
+        }
+        return specificationLoader.specForType(cls) 
+                .map(ObjectSpecification::getLogicalTypeName)
+                .map(logicalTypeName->Bookmark.of(logicalTypeName, identifier));
     }
 
     // -- SERIALIZING ADAPTER IMPLEMENTATION
@@ -139,8 +156,7 @@ public class BookmarkServiceDefault implements BookmarkService, SerializingAdapt
         if(isPredefinedSerializable(value.getClass())) {
             return (Serializable) value;
         } else {
-            val valueBookmark = bookmarkFor(value);
-            return valueBookmark;
+            return bookmarkForElseFail(value);
         }
     }
 
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java
index cdaf27d..5392d74 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java
@@ -623,7 +623,7 @@ public class WrapperFactoryDefault implements WrapperFactory {
             if (bookmark == null) {
                 return null;
             }
-            R domainObject = bookmarkService.lookup(bookmark, returnType);
+            R domainObject = bookmarkService.lookup(bookmark, returnType).orElse(null);
             if (metaModelService.sortOf(bookmark, RELAXED).isEntity()) {
                 domainObject = repositoryService.detach(domainObject);
             }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/isis/markups/jdo/IsisMarkupJdo.java b/examples/demo/domain/src/main/java/demoapp/dom/types/isis/markups/jdo/IsisMarkupJdo.java
index 7b51a89..42b099c 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/types/isis/markups/jdo/IsisMarkupJdo.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/isis/markups/jdo/IsisMarkupJdo.java
@@ -57,7 +57,7 @@ public class IsisMarkupJdo                                          // <.>
 //tag::class[]
     public String title() {
         return "Markup JDO entity: " +
-            bookmarkService.bookmarkFor(this).getIdentifier();
+            bookmarkService.bookmarkForElseFail(this).getIdentifier();
     }
 
     @PropertyLayout(fieldSetId = "read-only-properties", sequence = "1")
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/isisext/asciidocs/jdo/IsisAsciiDocJdo.java b/examples/demo/domain/src/main/java/demoapp/dom/types/isisext/asciidocs/jdo/IsisAsciiDocJdo.java
index ab68cbb..fab7060 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/types/isisext/asciidocs/jdo/IsisAsciiDocJdo.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/isisext/asciidocs/jdo/IsisAsciiDocJdo.java
@@ -57,7 +57,7 @@ public class IsisAsciiDocJdo                                          // <.>
 //tag::class[]
     public String title() {
         return "AsciiDoc JDO entity: " +
-            bookmarkService.bookmarkFor(this).getIdentifier();
+            bookmarkService.bookmarkForElseFail(this).getIdentifier();
     }
 
     @PropertyLayout(fieldSetId = "read-only-properties", sequence = "1")
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/isisext/markdowns/jdo/IsisMarkdownJdo.java b/examples/demo/domain/src/main/java/demoapp/dom/types/isisext/markdowns/jdo/IsisMarkdownJdo.java
index 293f0c6..2bfb0c0 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/types/isisext/markdowns/jdo/IsisMarkdownJdo.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/isisext/markdowns/jdo/IsisMarkdownJdo.java
@@ -57,7 +57,7 @@ public class IsisMarkdownJdo                                          // <.>
 //tag::class[]
     public String title() {
         return "Markdown JDO entity: " +
-            bookmarkService.bookmarkFor(this).getIdentifier();
+            bookmarkService.bookmarkForElseFail(this).getIdentifier();
 }
 
     @PropertyLayout(fieldSetId = "read-only-properties", sequence = "1")
diff --git a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/Object_recentCommands.java b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/Object_recentCommands.java
index 9e2fae1..9e0f564 100644
--- a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/Object_recentCommands.java
+++ b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/Object_recentCommands.java
@@ -18,6 +18,7 @@
  */
 package org.apache.isis.extensions.commandlog.impl.mixins;
 
+import java.util.Collections;
 import java.util.List;
 
 import javax.inject.Inject;
@@ -29,19 +30,16 @@ import org.apache.isis.applib.annotation.RestrictTo;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.mixins.layout.LayoutMixinConstants;
 import org.apache.isis.applib.mixins.system.HasInteractionId;
-import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.bookmark.BookmarkService;
 import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
 import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
 import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
 
 /**
- * @since 2.0 {@index}
- */
-
-/**
  * This mixin contributes a <tt>recentCommands</tt> action to any domain object
  * (unless also {@link HasInteractionId} - commands don't themselves have commands).
+ * 
+ * @since 2.0 {@index}
  */
 @Action(
         domainEvent = Object_recentCommands.ActionDomainEvent.class,
@@ -67,8 +65,9 @@ public class Object_recentCommands {
     }
 
     public List<CommandJdo> act() {
-        final Bookmark bookmark = bookmarkService.bookmarkFor(domainObject);
-        return commandServiceRepository.findRecentByTarget(bookmark);
+        return bookmarkService.bookmarkFor(domainObject)
+        .map(commandServiceRepository::findRecentByTarget)
+        .orElse(Collections.emptyList());
     }
     /**
      * Hide if the contributee is itself {@link HasInteractionId}
diff --git a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/T_recent.java b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/T_recent.java
index 843c8fd..ac24af5 100644
--- a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/T_recent.java
+++ b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/T_recent.java
@@ -18,13 +18,13 @@
  */
 package org.apache.isis.extensions.commandlog.impl.mixins;
 
+import java.util.Collections;
 import java.util.List;
 
 import javax.inject.Inject;
 
 import org.apache.isis.applib.annotation.Collection;
 import org.apache.isis.applib.annotation.CollectionLayout;
-import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.bookmark.BookmarkService;
 import org.apache.isis.applib.services.queryresultscache.QueryResultsCache;
 import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
@@ -52,12 +52,13 @@ public abstract class T_recent<T> {
     }
 
     private List<CommandJdo> findRecent() {
-        final Bookmark bookmark = bookmarkService.bookmarkFor(domainObject);
-        return queryResultsCache.execute(
+        return bookmarkService.bookmarkFor(domainObject)
+        .map(bookmark->queryResultsCache.execute(
                 () -> commandJdoRepository.findRecentByTarget(bookmark)
                 , T_recent.class
                 , "findRecentByTarget"
-                , domainObject);
+                , domainObject))
+        .orElse(Collections.emptyList());
     }
 
     @Inject CommandJdoRepository commandJdoRepository;
diff --git a/subdomains/excel/applib/src/main/java/org/apache/isis/subdomains/excel/applib/dom/util/CellMarshaller.java b/subdomains/excel/applib/src/main/java/org/apache/isis/subdomains/excel/applib/dom/util/CellMarshaller.java
index a785d09..0c12ef4 100644
--- a/subdomains/excel/applib/src/main/java/org/apache/isis/subdomains/excel/applib/dom/util/CellMarshaller.java
+++ b/subdomains/excel/applib/src/main/java/org/apache/isis/subdomains/excel/applib/dom/util/CellMarshaller.java
@@ -254,7 +254,7 @@ final class CellMarshaller {
     }
 
     private void setCellValueForBookmark(final Cell cell, final Object propertyAsObject, final String propertyAsTitle, final CellStyle cellStyle) {
-        Bookmark bookmark = bookmarkService.bookmarkForElseThrow(propertyAsObject);
+        Bookmark bookmark = bookmarkService.bookmarkForElseFail(propertyAsObject);
         setCellComment(cell, bookmark.toString());
         
         cell.setCellValue(propertyAsTitle);
diff --git a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/mixins/Object_clearHints.java b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/mixins/Object_clearHints.java
index e1b3688..9c72b65 100644
--- a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/mixins/Object_clearHints.java
+++ b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/mixins/Object_clearHints.java
@@ -81,7 +81,7 @@ public class Object_clearHints {
 
     public Object act() {
         if (getHintStoreUsingWicketSession() != null) {
-            val bookmark = bookmarkService.bookmarkForElseThrow(holder);
+            val bookmark = bookmarkService.bookmarkForElseFail(holder);
             val hintStore = getHintStoreUsingWicketSession();
             if(hintStore!=null) { // just in case
                 hintStore.removeAll(bookmark);