ctubbsii commented on code in PR #3678:
URL: https://github.com/apache/accumulo/pull/3678#discussion_r1287192471


##########
core/src/main/java/org/apache/accumulo/core/classloader/ClassLoaderUtil.java:
##########
@@ -75,11 +75,28 @@ static synchronized void resetContextFactoryForTests() {
 
   @SuppressWarnings("deprecation")
   public static ClassLoader getClassLoader(String context) {
-    if (context != null && !context.isEmpty()) {
-      return FACTORY.getClassLoader(context);
-    } else {
+    if (FACTORY == null) {
       return 
org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader.getClassLoader();
     }

Review Comment:
   FACTORY isn't supposed to be null here when this is called, or below where a 
similar check is made. I'm not sure I understand this part of these changes.
   
   If these methods can be called prior to the FACTORY being instantiated, then 
the FACTORY instantiation should be done lazily with a `Suppliers.memoize()`.



##########
core/src/main/java/org/apache/accumulo/core/classloader/ClassLoaderUtil.java:
##########
@@ -75,11 +75,28 @@ static synchronized void resetContextFactoryForTests() {
 
   @SuppressWarnings("deprecation")
   public static ClassLoader getClassLoader(String context) {
-    if (context != null && !context.isEmpty()) {
-      return FACTORY.getClassLoader(context);
-    } else {
+    if (FACTORY == null) {
       return 
org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader.getClassLoader();
     }
+    ClassLoader cl;
+    try {
+      cl = FACTORY.getClassLoader(context);
+      return (cl == null)

Review Comment:
   I do like the idea that the factory can return null, which just means, defer 
to the system classloader. That behavior should be added to the javadoc, though.



##########
core/src/main/java/org/apache/accumulo/core/classloader/ClassLoaderUtil.java:
##########
@@ -82,6 +82,14 @@ public static ClassLoader getClassLoader(String context) {
     }
   }
 
+  public static boolean isValidContext(String context) {
+    if (context != null && !context.isEmpty()) {

Review Comment:
   > > The empty string is the default value for `table.class.loader.context`, 
so it most definitely should be valid.
   > 
   > I'm not sure about that. There are no properties of PropertyType.STRING in 
Property.java whose default value is `null`. They all either have a value, or 
an empty string. I don't think that empty string is a valid String property 
value in all cases. I'm sure that in some cases it means the property is not 
set.
   
   I don't think we've done a good job in the internal config code of having a 
way to distinguish between set or not set, or allowing a value at one scope to 
be overridden by unsetting it at a different scope. This is a shortcoming in 
the current implementation, but far out of scope to fix here. The fact that 
`null` isn't used is really more of a byproduct of how commons-configuration 
works (it's really hard to set it as a value, because it either looks like an 
empty string, or looks like no entry). In theory, it could be a value, but in 
practice, you can't really set it. But empty string certainly can be set, and 
is set as the default in many properties. I don't think we have anything 
enforcing that `null` can't be the default value, though. If we're going to 
rely on that, we should probably enforce it.
   
   > 
   > > If the context property is not set for a particular table, the factory 
should still get consulted.
   > 
   > It's never worked like this. Even in `main` where the VFS stuff has been 
ripped out ClassLoaderUtil only consults the ContextClassLoaderFactory when the 
context name is set to a non-empty String.
   
   That is surprising to me. I was thinking it should always be consulted where 
there is a context possible. But now I'm not so sure what the right behavior 
should be, because there are too many edge cases and failure scenarios. Trying 
to put myself in the shoes of a user who has implemented a custom factory, it's 
getting harder to imagine how they might expect things to behave with respect 
to their implementation under all these scenarios. I'm leaning towards always 
consulting the factory, and leaving the "return null" mean "defer to system 
classloader", but I can also see an argument for "use context classloader 
factory only if a non-empty context is provided" (which is the current 
behavior). I'm fine with leaving the current behavior while I think about it 
some more.
   
   > However, I think I have a solution - I pushed the null and empty checks 
into the factory in 
[a4750ab](https://github.com/apache/accumulo/commit/a4750ab12a9694c8b2c0a5590451bdaefa311ed5).
   
   I think pushing these checks into the factory makes sense, and allowing the 
factory to return null, which causes Accumulo to use its system class loader. 
However, it's still a little unclear whether contexts that result in returning 
`null`, and deferring to the system class loader, are "valid" or not. Does 
"valid" mean "I won't cause an error" or does valid mean "I won't return null"?



-- 
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