Skip to content

Conversation

@vlsi
Copy link

@vlsi vlsi commented Oct 31, 2025

@epugh
Copy link
Contributor

epugh commented Oct 31, 2025

I'm okay with merging this, however, are there other instances of suppressed uses? I would love it if we could REMOVE the dependency...

@vlsi
Copy link
Author

vlsi commented Oct 31, 2025

I would really love to remove the dependency.
The only thing left is org.apache.commons.lang3.LocaleUtils.toLocale: https://github.com/apache/commons-lang/blob/bbfe331ea832a1f98809c9f5c058369e61b3af74/src/main/java/org/apache/commons/lang3/LocaleUtils.java#L400

Would you be comfortable copying the code to solr?


Frankly, I thought of making a fork of commons-lang3 with micro-modules like commons-stringutils, commons-localeutils, and so on to avoid duplicating the efforts on copying the code.
Unfortunately, commons team does not want to go with micro-modules: https://lists.apache.org/thread/9g1opd6l44dmck00b8gwg5qf1srngybl

@epugh
Copy link
Contributor

epugh commented Oct 31, 2025

I probably am not the right Java person to have an opinion on this... Seems like if that is all we need that "shading" is a thing right?

@dsmiley
Copy link
Contributor

dsmiley commented Nov 1, 2025

Please don't remove the JIRA link from the issue template, as it's a convenient link to click as a reviewer.

Any way, the code LGTM.

@vlsi
Copy link
Author

vlsi commented Nov 1, 2025

I'm not sure if Validate Changelog check is required or not. I don't think the change is user-visible.

@vlsi
Copy link
Author

vlsi commented Nov 1, 2025

I've completely removed commons-lang3 usage from the code.

The only missing bit is swagger:

|    +--- io.swagger.core.v3:swagger-integration-jakarta:2.2.22
|    |    +--- io.github.classgraph:classgraph:4.8.165
|    |    +--- io.swagger.core.v3:swagger-core-jakarta:2.2.22
|    |    |    +--- org.apache.commons:commons-lang3:3.14.0 -> 3.19.0

@vlsi vlsi force-pushed the containsIgnoreCase branch 2 times, most recently from e4e6719 to 99cfb7a Compare November 1, 2025 10:22
@vlsi
Copy link
Author

vlsi commented Nov 1, 2025

Note that I went with "forbid commons-lang on the compileClasspath and runtimeClasspath":

    configurations
        .matching {
            it.name == "compileClasspath" || it.name == "runtimeClasspath"
        }
        .configureEach {
            resolutionStrategy.eachDependency {
                if (requested.group == "org.apache.commons" && requested.name == "commons-lang3") {
                    throw new GradleException(
                        "Use JDK classes where possible, do not add org.apache.commons:commons-lang3 dependency")
                }
            }
        }

So if a transitive dependency selects to depend on commons-lang3, then the validation would trigger.

Unfortunately, Testcontainers depends on commons-compress which depends on commons-lang3 so we can't completely remove commons-lang3 from all the configurations yet.

@vlsi
Copy link
Author

vlsi commented Nov 1, 2025

Spring context fails for some reason.
Looks like something still depends on NoClassDefFoundError: org/apache/commons/lang3/tuple/Pair

 2> Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
  2> 11384 ERROR (SUITE-S3ReadWriteTest-seed#[DB786EC85E5C08B8]-worker) [n: c: s: r: x: t:] o.s.b.SpringApplication Application run failed
  2>           => org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'fileStoreController' defined in class path resource [com/adobe/testing/s3mock/S3MockConfiguration.class]: Unsatisfied dependency expressed through method 'fileStoreController' parameter 0: Error creating bean with name 'objectService' defined in class path resource [com/adobe/testing/s3mock/service/ServiceConfiguration.class]: Post-processing of merged bean definition failed
  2> 	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:795)
  2> org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'fileStoreController' defined in class path resource [com/adobe/testing/s3mock/S3MockConfiguration.class]: Unsatisfied dependency expressed through method 'fileStoreController' parameter 0: Error creating bean with name 'objectService' defined in class path resource [com/adobe/testing/s3mock/service/ServiceConfiguration.class]: Post-processing of merged bean definition failed
  2> 	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:795) ~[spring-beans-6.1.12.jar:6.1.12]
  2> 	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:542) ~[spring-beans-6.1.12.jar:6.1.12]
  2> 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1355) ~[spring-beans-6.1.12.jar:6.1.12]
  2> 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1185) ~[spring-beans-6.1.12.jar:6.1.12]
  2> 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562) ~[spring-beans-6.1.12.jar:6.1.12]
  2> 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[spring-beans-6.1.12.jar:6.1.12]
  2> 	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337) ~[spring-beans-6.1.12.jar:6.1.12]
  2> 	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.12.jar:6.1.12]
  2> 	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335) ~[spring-beans-6.1.12.jar:6.1.12]
  2> 	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.1.12.jar:6.1.12]
  2> 	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975) ~[spring-beans-6.1.12.jar:6.1.12]
  2> 	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:971) ~[spring-context-6.1.12.jar:6.1.12]
  2> 	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:625) ~[spring-context-6.1.12.jar:6.1.12]
  2> 	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.3.3.jar:3.3.3]
  2> 	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) [spring-boot-3.3.3.jar:3.3.3]
  2> 	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) [spring-boot-3.3.3.jar:3.3.3]
  2> 	at org.springframework.boot.SpringApplication.run(SpringApplication.java:335) [spring-boot-3.3.3.jar:3.3.3]
  2> 	at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:149) [spring-boot-3.3.3.jar:3.3.3]
  2> 	at com.adobe.testing.s3mock.S3MockApplication.start(S3MockApplication.java:199) [s3mock-3.12.0.jar:?]
  2> 	at com.adobe.testing.s3mock.testsupport.common.S3MockStarter.start(S3MockStarter.java:173) [s3mock-testsupport-common-3.12.0.jar:?]
  2> 	at com.adobe.testing.s3mock.junit4.S3MockRule.access$000(S3MockRule.java:46) [s3mock-junit4-3.12.0.jar:?]
  2> 	at com.adobe.testing.s3mock.junit4.S3MockRule$1.evaluate(S3MockRule.java:68) [s3mock-junit4-3.12.0.jar:?]
  2> 	at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36) [randomizedtesting-runner-2.8.3.jar:?]
  2> 	at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36) [randomizedtesting-runner-2.8.3.jar:?]
  2> 	at org.apache.lucene.tests.util.AbstractBeforeAfterRule$1.evaluate(AbstractBeforeAfterRule.java:43) [lucene-test-framework-10.3.1.jar:10.3.1 51190f35a16d2ce433139abfe0fd8365791b352a - 2025-10-02 09:50:16]
  2> 	at com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule$1.evaluate(SystemPropertiesRestoreRule.java:80) [randomizedtesting-runner-2.8.3.jar:?]
  2> 	at org.junit.rules.RunRules.evaluate(RunRules.java:20) [junit-4.13.2.jar:4.13.2]
  2> 	at org.apache.lucene.tests.util.AbstractBeforeAfterRule$1.evaluate(AbstractBeforeAfterRule.java:43) [lucene-test-framework-10.3.1.jar:10.3.1 51190f35a16d2ce433139abfe0fd8365791b352a - 2025-10-02 09:50:16]
  2> 	at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36) [randomizedtesting-runner-2.8.3.jar:?]
  2> 	at org.apache.lucene.tests.util.TestRuleStoreClassName$1.evaluate(TestRuleStoreClassName.java:38) [lucene-test-framework-10.3.1.jar:10.3.1 51190f35a16d2ce433139abfe0fd8365791b352a - 2025-10-02 09:50:16]
  2> 	at com.carrotsearch.randomizedtesting.rules.NoShadowingOrOverridesOnMethodsRule$1.evaluate(NoShadowingOrOverridesOnMethodsRule.java:40) [randomizedtesting-runner-2.8.3.jar:?]
  2> 	at com.carrotsearch.randomizedtesting.rules.NoShadowingOrOverridesOnMethodsRule$1.evaluate(NoShadowingOrOverridesOnMethodsRule.java:40) [randomizedtesting-runner-2.8.3.jar:?]
  2> 	at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36) [randomizedtesting-runner-2.8.3.jar:?]
  2> 	at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36) [randomizedtesting-runner-2.8.3.jar:?]
  2> 	at org.apache.lucene.tests.util.TestRuleAssertionsRequired$1.evaluate(TestRuleAssertionsRequired.java:53) [lucene-test-framework-10.3.1.jar:10.3.1 51190f35a16d2ce433139abfe0fd8365791b352a - 2025-10-02 09:50:16]
  2> 	at org.apache.lucene.tests.util.AbstractBeforeAfterRule$1.evaluate(AbstractBeforeAfterRule.java:43) [lucene-test-framework-10.3.1.jar:10.3.1 51190f35a16d2ce433139abfe0fd8365791b352a - 2025-10-02 09:50:16]
  2> 	at org.apache.lucene.tests.util.TestRuleMarkFailure$1.evaluate(TestRuleMarkFailure.java:44) [lucene-test-framework-10.3.1.jar:10.3.1 51190f35a16d2ce433139abfe0fd8365791b352a - 2025-10-02 09:50:16]
  2> 	at org.apache.lucene.tests.util.TestRuleIgnoreAfterMaxFailures$1.evaluate(TestRuleIgnoreAfterMaxFailures.java:60) [lucene-test-framework-10.3.1.jar:10.3.1 51190f35a16d2ce433139abfe0fd8365791b352a - 2025-10-02 09:50:16]
   >         at app//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
   >         at app//org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335)
   >         at app//org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
   >         at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975)
   >         at app//org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:971)
   >         at app//org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:625)
   >         at app//org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
   >         at app//org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
   >         at app//org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
   >         at app//org.springframework.boot.SpringApplication.run(SpringApplication.java:335)
   >         at app//org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:149)
   >         at app//com.adobe.testing.s3mock.S3MockApplication.start(S3MockApplication.java:199)
   >         at app//com.adobe.testing.s3mock.testsupport.common.S3MockStarter.start(S3MockStarter.java:173)
   >         at app//com.adobe.testing.s3mock.junit4.S3MockRule.access$000(S3MockRule.java:46)
   >         at app//com.adobe.testing.s3mock.junit4.S3MockRule$1.evaluate(S3MockRule.java:68)
   >         at app//com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
   >         at app//com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
   >         at app//org.apache.lucene.tests.util.AbstractBeforeAfterRule$1.evaluate(AbstractBeforeAfterRule.java:43)
   >         at app//com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule$1.evaluate(SystemPropertiesRestoreRule.java:80)
   >         at app//org.junit.rules.RunRules.evaluate(RunRules.java:20)
   >         at app//org.apache.lucene.tests.util.AbstractBeforeAfterRule$1.evaluate(AbstractBeforeAfterRule.java:43)
   >         at app//com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
   >         at app//org.apache.lucene.tests.util.TestRuleStoreClassName$1.evaluate(TestRuleStoreClassName.java:38)
   >         at app//com.carrotsearch.randomizedtesting.rules.NoShadowingOrOverridesOnMethodsRule$1.evaluate(NoShadowingOrOverridesOnMethodsRule.java:40)
   >         at app//com.carrotsearch.randomizedtesting.rules.NoShadowingOrOverridesOnMethodsRule$1.evaluate(NoShadowingOrOverridesOnMethodsRule.java:40)
   >         at app//com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
   >         at app//com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
   >         at app//org.apache.lucene.tests.util.TestRuleAssertionsRequired$1.evaluate(TestRuleAssertionsRequired.java:53)
   >         at app//org.apache.lucene.tests.util.AbstractBeforeAfterRule$1.evaluate(AbstractBeforeAfterRule.java:43)
   >         at app//org.apache.lucene.tests.util.TestRuleMarkFailure$1.evaluate(TestRuleMarkFailure.java:44)
   >         at app//org.apache.lucene.tests.util.TestRuleIgnoreAfterMaxFailures$1.evaluate(TestRuleIgnoreAfterMaxFailures.java:60)
   >         at app//org.apache.lucene.tests.util.TestRuleIgnoreTestSuites$1.evaluate(TestRuleIgnoreTestSuites.java:47)
   >         at app//org.junit.rules.RunRules.evaluate(RunRules.java:20)
   >         at app//com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
   >         at app//com.carrotsearch.randomizedtesting.ThreadLeakControl$StatementRunner.run(ThreadLeakControl.java:390)
   >         at app//com.carrotsearch.randomizedtesting.ThreadLeakControl.lambda$forkTimeoutingTask$0(ThreadLeakControl.java:850)
   >         at [email protected]/java.lang.Thread.run(Thread.java:1583)
   > 
   >         Caused by:
   >         org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'objectService' defined in class path resource [com/adobe/testing/s3mock/service/ServiceConfiguration.class]: Post-processing of merged bean definition failed
   >             at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:577)
   >             at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
   >             at app//org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337)
   >             at app//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
   >             at app//org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335)
   >             at app//org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
   >             at app//org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254)
   >             at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1443)
   >             at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353)
   >             at app//org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:904)
   >             at app//org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:782)
   >             ... 43 more
   > 
   >             Caused by:
   >             java.lang.IllegalStateException: Failed to introspect Class [com.adobe.testing.s3mock.service.ObjectService] from ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader@4617c264]
   >                 at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:483)
   >                 at org.springframework.util.ReflectionUtils.doWithLocalMethods(ReflectionUtils.java:320)
   >                 at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.buildLifecycleMetadata(InitDestroyAnnotationBeanPostProcessor.java:297)
   >                 at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.findLifecycleMetadata(InitDestroyAnnotationBeanPostProcessor.java:274)
   >                 at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.findLifecycleMetadata(InitDestroyAnnotationBeanPostProcessor.java:203)
   >                 at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(InitDestroyAnnotationBeanPostProcessor.java:182)
   >                 at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(CommonAnnotationBeanPostProcessor.java:311)
   >                 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:1103)
   >                 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:574)
   >                 ... 53 more
   > 
   >                 Caused by:
   >                 java.lang.NoClassDefFoundError: org/apache/commons/lang3/tuple/Pair
   >                     at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
   >                     at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3578)
   >                     at java.base/java.lang.Class.getDeclaredMethods(Class.java:2676)
   >                     at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:465)
   >                     ... 61 more
   > 
   >                     Caused by:
   >                     java.lang.ClassNotFoundException: org.apache.commons.lang3.tuple.Pair
   >                         at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
   >                         at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
   >                         at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
   >                         ... 65 more

@vlsi vlsi force-pushed the containsIgnoreCase branch from 2c4450c to a027beb Compare November 1, 2025 11:35
@vlsi
Copy link
Author

vlsi commented Nov 1, 2025

There was exclude group: 'org.apache.commons', module: 'commons-lang3', thus the NCDFE.

I've filed:

   > Could not resolve org.apache.commons:commons-lang3:3.13.0.
     Required by:
         project :solr:modules:sql > org.apache.calcite:calcite-core:1.37.0
      > Use JDK classes where possible, do not add org.apache.commons:commons-lang3 dependency

@vlsi vlsi force-pushed the containsIgnoreCase branch 2 times, most recently from de1c6d9 to 34ec35f Compare November 1, 2025 12:12
@github-actions
Copy link

github-actions bot commented Jan 2, 2026

This PR has had no activity for 60 days and is now labeled as stale. Any new activity will remove the stale label. To attract more reviewers, please tag people who might be familiar with the code area and/or notify the [email protected] mailing list. To exempt this PR from being marked as stale, make it a draft PR or add the label "exempt-stale". If left unattended, this PR will be closed after another 60 days of inactivity. Thank you for your contribution!

@github-actions github-actions bot added the stale PR not updated in 60 days label Jan 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants