jbonofre commented on code in PR #739:
URL: https://github.com/apache/camel-karaf/pull/739#discussion_r3872608121


##########
core/camel-core-osgi/src/main/java/org/apache/camel/karaf/core/OsgiTypeConverter.java:
##########
@@ -203,7 +278,7 @@ public TypeConverter lookup(Class<?> toType, Class<?> 
fromType) {
 
     @Override
     public void setInjector(Injector injector) {

Review Comment:
   **`setInjector` only records a replay lambda and never updates the 
`injector` field, so every rebuilt registry is constructed with the 
constructor-time injector and loads its core converters before the replay 
corrects it.**
   
   `createRegistry()` passes the `final` field `this.injector` to `new 
OsgiDefaultTypeConverter(...)`, then calls `answer.init()` and 
`answer.loadCoreAndFastTypeConverters()`, and only afterwards calls 
`replayProgrammaticRegistrations(answer)`. So after a rebuild, converters 
instantiated during core loading used the **old** injector; the configured one 
is swapped in only after the fact, and anything already created keeps the stale 
reference.
   
   `TYPE_CONVERTER_EXISTS_KEY` and `TYPE_CONVERTER_EXISTS_LOGGING_LEVEL_KEY` 
have the same ordering problem, and it compounds the replay issue on 
`replayProgrammaticRegistrations`: a context configured `Override` or `Fail` 
has all its core and loader converters registered under the constructor 
defaults (`Ignore` / `DEBUG`), and the real policy only takes effect partway 
through the replay, in insertion order.
   
   This is strictly better than pre-PR behaviour (where the setting was lost 
entirely), so not a blocker — but "brought back to the same state" is not what 
happens.
   
   _AI-generated review on behalf of JB Onofré_



##########
core/camel-core-osgi/src/main/java/org/apache/camel/karaf/core/OsgiTypeConverter.java:
##########
@@ -279,28 +358,73 @@ public Set<ClassLoader> getClassLoaders() {
             throw new RuntimeCamelException("Error loading CoreTypeConverter 
due: " + e.getMessage(), e);
         }
 
-        // Load the type converters the tracker has been tracking
-        // Here we need to use the ServiceReference to check the ranking
-        ServiceReference<TypeConverterLoader>[] serviceReferences = 
this.tracker.getServiceReferences();
-        if (serviceReferences != null) {
-            ArrayList<ServiceReference<TypeConverterLoader>> servicesList =
-                    new ArrayList<>(Arrays.asList(serviceReferences));
-            // Just make sure we install the high ranking fallback converter 
at last
-            Collections.sort(servicesList);
-            for (ServiceReference<TypeConverterLoader> sr : servicesList) {
-                try {
-                    LOG.debug("loading type converter from bundle: {}", 
sr.getBundle().getSymbolicName());
-                    
((TypeConverterLoader)this.tracker.getService(sr)).load(answer);
-                } catch (Throwable t) {
-                    throw new RuntimeCamelException("Error loading type 
converters from service: " + sr + " due: " + t.getMessage(), t);
-                }
+        // Load the type converters the tracker has been tracking. These come 
from our own map rather than from
+        // tracker.getServiceReferences()/getService(): this runs while 
holding this instance's monitor, and
+        // calling back into the tracker from here is what would establish a 
lock ordering against the framework.
+        List<ServiceReference<TypeConverterLoader>> servicesList = new 
ArrayList<>(trackedLoaders.keySet());
+        // Just make sure we install the high ranking fallback converter at 
last
+        Collections.sort(servicesList);
+        for (ServiceReference<TypeConverterLoader> sr : servicesList) {
+            TypeConverterLoader loader = trackedLoaders.get(sr);
+            if (loader == null) {
+                // unregistered between the snapshot and here
+                continue;
+            }
+            try {
+                LOG.debug("loading type converter from bundle: {}", 
sr.getBundle().getSymbolicName());
+                loader.load(answer);
+            } catch (Throwable t) {
+                throw new RuntimeCamelException("Error loading type converters 
from service: " + sr + " due: " + t.getMessage(), t);
             }
         }
 
+        replayProgrammaticRegistrations(answer);
+
         LOG.trace("Created TypeConverter: {}", answer);
         return answer;
     }
 
+    /**
+     * Re-applies everything that was registered through this facade rather 
than by a
+     * {@link TypeConverterLoader}, in the order it was originally applied.
+     */
+    private void replayProgrammaticRegistrations(DefaultTypeConverter 
registry) {
+        if (programmaticRegistrations.isEmpty()) {
+            return;
+        }
+        LOG.debug("Replaying {} programmatic registration(s) onto the rebuilt 
type converter registry",
+                programmaticRegistrations.size());
+        for (Consumer<TypeConverterRegistry> registration : 
programmaticRegistrations.values()) {
+            registration.accept(registry);
+        }
+    }
+
+    /**

Review Comment:
   **Two consecutive Javadoc blocks: this one is orphaned by the `/** */` for 
`programmaticRegistrationCount()` that follows, so `register()` ends up with no 
Javadoc and the surviving comment documents the wrong method.**
   
   Java attaches only the last block before a declaration. This block — the 
load-bearing explanation of why apply-and-record has to be atomic, which both 
the commit message and the PR description lean on — becomes a dangling comment 
attached to nothing, and `register()` at line 421 is undocumented. The `{@link 
#getDelegate()}` reference in it is invisible to doclint too.
   
   Looks like a rebase/squash artifact; moving this block down to immediately 
precede `register()` fixes it.
   
   _AI-generated review on behalf of JB Onofré_



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to