henrybear327 commented on code in PR #10760:
URL: https://github.com/apache/ozone/pull/10760#discussion_r4262837832


##########
hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/local/LocalOzoneCluster.java:
##########
@@ -254,6 +282,11 @@ public void start() throws Exception {
       startOm(prepared.getConfiguration());
       startDatanodes(prepared.getDatanodeConfigurations());
       waitForClusterReadiness(config.getStartupTimeout());
+      if (config.isReconEnabled()) {
+        startRecon(prepared.getConfiguration());
+        waitForHttpEndpointReadiness(getReconEndpoint(), "Recon",
+            config.getStartupTimeout());
+      }
       if (config.isS3gEnabled()) {
         startS3Gateway(prepared.getConfiguration());
       }

Review Comment:
   Starting them concurrently throws an exception for me. I changed `start()` 
to start Recon and S3 Gateway on two threads and ran the s3g=true, recon=true 
case of `TestLocalOzoneRecon#enabledServicesServeAndStopOnClose` five times, 
one JVM per run. 
   
   Recon failed every time. S3 Gateway finished starting in under a second, and 
Recon failed 1.2 to 1.5 s in, when it started its HTTP server:
   
   ```
   java.io.IOException: Unable to initialize WebAppContext
        at 
org.apache.hadoop.hdds.server.http.HttpServer2.start(HttpServer2.java:1369)
        at 
org.apache.hadoop.hdds.server.http.BaseHttpServer.start(BaseHttpServer.java:357)
        at org.apache.hadoop.ozone.recon.ReconServer.start(ReconServer.java:325)
        ...
   Caused by: javax.ws.rs.WebApplicationException: Trying to register multiple 
service locators into single service locator application.
        at 
org.glassfish.jersey.ext.cdi1x.internal.SingleInjectionManagerStore.registerInjectionManager(SingleInjectionManagerStore.java:40)
        at 
org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider.addInjectionManager(CdiComponentProvider.java:569)
        at 
org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider.initialize(CdiComponentProvider.java:163)
        at 
org.glassfish.jersey.ext.cdi1x.internal.CdiServerComponentProvider.initialize(CdiServerComponentProvider.java:39)
        ...
        at 
org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:154)
   ```
   
   ---
   
   I tired to debug the situation and it seems to be related to Jersey's CDI 
integration and the fact that we run everything under one JVM. 
   
   The root cause might be at Jersey's CDI integration (jersey-cdi1x), which S3 
Gateway uses. When Recon's Jersey app initializes, `CdiServerComponentProvider` 
finds a Weld container that S3 Gateway started and tries to register Recon's 
app with Jersey's CDI extension in that container. The extension keeps its app 
in a `SingleInjectionManagerStore`, which already holds S3 Gateway's app, so it 
throws.
   
   The reason for it is that `ozone local` runs every service in one JVM with 
one classpath. `ozone-tools` depends on both `ozone-recon` and 
`ozone-s3gateway`, so jersey-cdi1x runs for Recon's Jersey app too, and it 
looks up the CDI container JVM-wide through `CDI.current()`. Before S3 Gateway 
starts there is no Weld container, the lookup returns nothing, and jersey-cdi1x 
does nothing for Recon. So Recon has to start before S3 Gateway, which is the 
current order.
   
   ---
   
   Not entirely sure if the analysis is correct, and if there is any fix we can 
go about it in the meantime to make things able to start concurrently. 



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


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to