[ 
https://issues.apache.org/jira/browse/HDDS-13077?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Sammi Chen reassigned HDDS-13077:
---------------------------------

    Assignee: Sammi Chen

> [compatibility] IllegalArgumentException: No enum constant on using old 
> filesystem jars in the classpath first
> --------------------------------------------------------------------------------------------------------------
>
>                 Key: HDDS-13077
>                 URL: https://issues.apache.org/jira/browse/HDDS-13077
>             Project: Apache Ozone
>          Issue Type: Bug
>    Affects Versions: 2.0.0
>            Reporter: Soumitra Sulav
>            Assignee: Sammi Chen
>            Priority: Blocker
>
> The issue appears to stem from an incompatibility between old and new Ozone 
> client jars. That’s due to a config introduced in the following change:
> HDDS-11656 – Default native ACL limits to user and user's primary group
> Code Link: 
> [apache/ozone#7455|https://github.com/apache/ozone/pull/7455/files#diff-7c1277dbfbebe1cb4dcbab71bb2ebd6836b6fa7adfeed8b67fbd5787a464e4c8R47]
> It may be caused by a mismatch between the runtime configuration values and 
> the compiled client code/code from the classpath jars.
> Previously, the server-side default for ozone.om.group.rights was:
> {code:java}
> ozone.om.group.rights = ALL
> {code}
> Older clients were designed to interpret this single ACLType enum value 
> correctly.
> However, after the recent update (HDDS-11656), the server default was changed 
> to a comma-delimited value:
> {code:java}
> ozone.om.group.rights = READ,LIST
> {code}
> At the same time, newer client code was updated to parse and handle multiple 
> ACLType values from this config.
> If a client with older compiled code runs against a configuration that 
> contains the new multi-value default (READ,LIST), it currently fails at 
> runtime, since it attempts to interpret the full string "READ, LIST" as a 
> single enum value, which doesn't exist, and throws an 
> IllegalArgumentException.
> Error stacktrace:
> {code:java}
> 25/05/15 10:02:41 ERROR client.OzoneClientFactory: Couldn't create RpcClient 
> protocol exception:
> java.lang.IllegalArgumentException: No enum constant 
> org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType.READ, LIST
>       at java.base/java.lang.Enum.valueOf(Enum.java:240)
>       at 
> org.apache.hadoop.ozone.security.acl.IAccessAuthorizer$ACLType.valueOf(IAccessAuthorizer.java:48)
>       at 
> org.apache.hadoop.ozone.security.acl.OzoneAclConfig.getGroupDefaultRights(OzoneAclConfig.java:62)
>       at 
> org.apache.hadoop.ozone.client.rpc.RpcClient.<init>(RpcClient.java:232)
>       at 
> org.apache.hadoop.ozone.client.OzoneClientFactory.getClientProtocol(OzoneClientFactory.java:248)
>       at 
> org.apache.hadoop.ozone.client.OzoneClientFactory.getRpcClient(OzoneClientFactory.java:115)
>       at 
> org.apache.hadoop.fs.ozone.BasicRootedOzoneClientAdapterImpl.<init>(BasicRootedOzoneClientAdapterImpl.java:191)
>       at 
> org.apache.hadoop.fs.ozone.RootedOzoneClientAdapterImpl.<init>(RootedOzoneClientAdapterImpl.java:51)
>       at 
> org.apache.hadoop.fs.ozone.RootedOzoneFileSystem.createAdapter(RootedOzoneFileSystem.java:97)
>       at 
> org.apache.hadoop.fs.ozone.BasicRootedOzoneFileSystem.initialize(BasicRootedOzoneFileSystem.java:185)
>       at 
> org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:3451)
>       at org.apache.hadoop.fs.FileSystem.access$300(FileSystem.java:161)
>       at 
> org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:3556)
>       at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:3503)
>       at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:521)
>       at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:269)
>       at OzoneClientRepro.main(OzoneClientRepro.java:20)
> 25/05/15 10:02:41 WARN fs.FileSystem: Failed to initialize fileystem 
> ofs://ozone1747280928/: java.io.IOException: Couldn't create RpcClient 
> protocol
> Exception in thread "main" java.io.IOException: Couldn't create RpcClient 
> protocol
>       at 
> org.apache.hadoop.ozone.client.OzoneClientFactory.getClientProtocol(OzoneClientFactory.java:257)
>       at 
> org.apache.hadoop.ozone.client.OzoneClientFactory.getRpcClient(OzoneClientFactory.java:115)
>       at 
> org.apache.hadoop.fs.ozone.BasicRootedOzoneClientAdapterImpl.<init>(BasicRootedOzoneClientAdapterImpl.java:191)
>       at 
> org.apache.hadoop.fs.ozone.RootedOzoneClientAdapterImpl.<init>(RootedOzoneClientAdapterImpl.java:51)
>       at 
> org.apache.hadoop.fs.ozone.RootedOzoneFileSystem.createAdapter(RootedOzoneFileSystem.java:97)
>       at 
> org.apache.hadoop.fs.ozone.BasicRootedOzoneFileSystem.initialize(BasicRootedOzoneFileSystem.java:185)
>       at 
> org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:3451)
>       at org.apache.hadoop.fs.FileSystem.access$300(FileSystem.java:161)
>       at 
> org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:3556)
>       at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:3503)
>       at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:521)
>       at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:269)
>       at OzoneClientRepro.main(OzoneClientRepro.java:20)
> Caused by: java.lang.IllegalArgumentException: No enum constant 
> org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType.READ, LIST
>       at java.base/java.lang.Enum.valueOf(Enum.java:240)
>       at 
> org.apache.hadoop.ozone.security.acl.IAccessAuthorizer$ACLType.valueOf(IAccessAuthorizer.java:48)
>       at 
> org.apache.hadoop.ozone.security.acl.OzoneAclConfig.getGroupDefaultRights(OzoneAclConfig.java:62)
>       at 
> org.apache.hadoop.ozone.client.rpc.RpcClient.<init>(RpcClient.java:232)
>       at 
> org.apache.hadoop.ozone.client.OzoneClientFactory.getClientProtocol(OzoneClientFactory.java:248)
>       ... 12 more
> {code}
> *Steps to reproduce and validate the Incompatibility*
> Write a minimal client that performs a simple read operation from the Ozone 
> filesystem:
> {{cat src/main/java/OzoneClientRepro.java}}
> {code:java}
> import org.apache.hadoop.conf.Configuration;
> import org.apache.hadoop.fs.FileSystem;
> import org.apache.hadoop.fs.FileStatus;
> import org.apache.hadoop.fs.Path;
> public class OzoneClientRepro {
>     public static void main(String[] args) throws Exception {
>         if (args.length < 1) {
>             System.err.println("Usage: java OzoneClientRepro <ofs-uri>");
>             System.exit(1);
>         }
>         String ofsUri = args[0];  // Example: ofs://om/
>         Configuration conf = new Configuration();
>         conf.set("fs.defaultFS", ofsUri);
>         System.out.println("Connecting to Ozone filesystem: " + ofsUri);
>         FileSystem fs = FileSystem.get(conf);
>         System.out.println("Listing contents of /vol/bucket:");
>         FileStatus[] statuses = fs.listStatus(new Path("/vol/bucket"));
>         for (FileStatus status: statuses) {
>             System.out.printf("- %s\t%s\n",
>                 status.isDirectory() ? "[DIR]" : "[FILE]",
>                 status.getPath().toString()
>             );
>         }
>         fs.close();
>     }
> }
> {code}
> Run this client against the following server setups:
> {{java -cp 
> "target/ozone-old-client-repro-1.0-SNAPSHOT.jar:$old_fs:$new_fs:$other_deps" 
> OzoneClientRepro ofs://om/}}
> ||Combination of FileSystem Jar||Classpaths used in CLI||Observations||
> |Old only|$old_fs:$other_deps|Works - Client runs successfully with old 
> server classes|
> |New only|$new_fs:$other_deps|Works - Client runs successfully with matching 
> new server classes|
> |New first, then Old|$new_fs:$old_fs:$other_deps|Works - Classpath order 
> ensures new enums are loaded, old jar doesn't interfere|
> |Old first, then New|$old_fs:$new_fs:$other_deps|*{color:#FF0000}Fails - 
> Caused by: java.lang.IllegalArgumentException: No enum constant 
> org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType.READ, 
> LIST{color}*|
> Just adding the below property in /etc/ozone/conf/ozone-site.xml makes it 
> work:
> {code:java}
>   <property>
>     <name>ozone.om.group.rights</name>
>     <value>ALL</value>
>   </property>
> {code}
> *RCA (by [~sammichen]*
> This is the root cause of why old jar with new configuration.
> In OzoneConfiguration.java, it finds and loads “ozone-default-generated.xml” 
> from all jars in the class path. In this old jar and new jar mixed 
> environment, although the class from new jar is not used and loaded, but the 
> “ozone-default-generated.xml” in the new jar is loaded. So the configuration 
> loaded from old jar is overwritten by configuration in the new jar.
> {code:java}
>   Enumeration<URL> generatedDefaults =
>           OzoneConfiguration.class.getClassLoader().getResources(
>               "ozone-default-generated.xml");
> {code}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

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

Reply via email to