Joker-5 commented on code in PR #15642:
URL: https://github.com/apache/kafka/pull/15642#discussion_r1547690392


##########
connect/runtime/src/test/java/org/apache/kafka/connect/integration/ConnectorValidationIntegrationTest.java:
##########
@@ -69,6 +69,9 @@ public static void setup() {
         Map<String, String> workerProps = new HashMap<>();
         workerProps.put(GROUP_ID_CONFIG, WORKER_GROUP_ID);
 
+        // Work around a circular-dependency in TestPlugins.
+        TestPlugins.pluginPath();

Review Comment:
   @vamossagar12 If we don't add this, methods which use `TestPlugins`  will 
have erroneous behavior. In particular:
   ```
   [2024-04-02 19:16:25,977] ERROR Could not set up plugin test jars 
(org.apache.kafka.connect.runtime.isolation.TestPlugins:258)
   java.lang.NullPointerException
        at 
org.apache.kafka.connect.runtime.isolation.TestPlugins$TestPlugin.values(TestPlugins.java:69)
        at 
org.apache.kafka.connect.runtime.isolation.TestPlugins.<clinit>(TestPlugins.java:251)
        at 
org.apache.kafka.connect.runtime.isolation.TestPlugins$TestPlugin.<clinit>(TestPlugins.java:128)
        at 
org.apache.kafka.connect.integration.ConnectorValidationIntegrationTest.testConnectorHasConverterWithNoSuitableConstructor(ConnectorValidationIntegrationTest.java:337)
   ...
   ```
   I found the reason behind it:
   
   >TL;DR
   The whole error occurred because the circle: inner class(some field depend 
on outer class in the \<clinit> method) -> outer class(some line in static code 
block depend on inner class in the \<clinit> method) -> inner class
   
   1. There's a `private final Predicate<String> removeRuntimeClasses` field in 
the inner class 
`org.apache.kafka.connect.runtime.isolation.TestPlugins.TestPlugin`.
   2. Some enums such as `BAD_PACKAGING_MISSING_SUPERCLASS` in (1)'s field will 
depend on `private static final Predicate<String> REMOVE_CLASS_FILTER = s -> 
s.contains("NonExistentInterface")` in the outer 
class(`org.apache.kafka.connect.runtime.isolation.TestPlugins`).
   3. When test mothod such as 
`testConnectorHasConverterWithNoSuitableConstructor` is running, JVM will call 
\<clinit> method to initialize the inner 
class(`org.apache.kafka.connect.runtime.isolation.TestPlugins.TestPlugin`).
   4. But some enum use the field(`removeRuntimeClasses`) in the outer 
class(`private static final Predicate<String> REMOVE_CLASS_FILTER = s -> 
s.contains("NonExistentInterface")`), so at that time JVM has to call \<clinit> 
method to initialize the outer 
class(`org.apache.kafka.connect.runtime.isolation.TestPlugins`).
   5. In the outer class, there's a static code block which used the inner 
class. But the inner class have not been initialized, the circular-dependency 
just happened, which result in that error log.
   ```java
       static {
           Throwable err = null;
           Map<String, Path> pluginJars = new HashMap<>();
           try {
               for (TestPlugin testPlugin : TestPlugin.values()) { // see this 
line
                   if (pluginJars.containsKey(testPlugin.resourceDir())) {
                       log.debug("Skipping recompilation of " + 
testPlugin.resourceDir());
                   }
                   pluginJars.put(testPlugin.resourceDir(), 
createPluginJar(testPlugin.resourceDir(), testPlugin.removeRuntimeClasses()));
               }
           } catch (Throwable e) {
               log.error("Could not set up plugin test jars", e);
               err = e;
           }
           PLUGIN_JARS = Collections.unmodifiableMap(pluginJars);
           INITIALIZATION_EXCEPTION = err;
       }
   ```
   
   So that's why I added the code.



-- 
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: jira-unsubscr...@kafka.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to