Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SOLR-16427: Enable error-prone ClassInitializationDeadlock rule #2881

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

malliaridis
Copy link
Contributor

@malliaridis malliaridis commented Nov 21, 2024

https://issues.apache.org/jira/browse/SOLR-16427

Description

With the ClassInitializationDeadlock rule error-prone checks for possible class initialization deadlocks. See error-prone documentation for details about the problem this rule is fixing.

Solution

Following the suggestions of error-prone, the possible deadlocks are resolved by introducing separate classes for static members.

You may review commits individually for a better overview.

This PR is not backwards compatible and public static members are moved to separate classes, potentially breaking third-party code that uses these static members.

Tests

Tests were not altered, only existing references to static members are updated.

Checklist

Please review the following and check all that apply:

  • I have reviewed the guidelines for How to Contribute and my code conforms to the standards described there to the best of my ability.
  • I have created a Jira issue and added the issue ID to my pull request title.
  • I have given Solr maintainers access to contribute to my PR branch. (optional but recommended, not available for branches on forks living under an organisation)
  • I have developed this patch against the main branch.
  • I have run ./gradlew check.
  • I have added tests for my changes.
  • I have added documentation for the Reference Guide

Copy link
Contributor

@dsmiley dsmiley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First, thanks for working on this. It's been a problem for Lucene & Solr over the years. @uschindler , you have always been involved in this topic so I'm tagging you for any additional review.

I suggest limiting this PR to be only main, without any concern for deprecating stuff. By and large, you were deprecating very internal things.

TimeSource has annoyed me; I filed SOLR-17573 to improve that (albeit may be controversial).

qParserPlugins.init(QParserPlugin.standardPlugins, this);
valueSourceParsers.init(ValueSourceParser.standardValueSourceParsers, this);
transformerFactories.init(TransformerFactory.defaultFactories, this);
qParserPlugins.init(QParserPlugins.standardPlugins, this);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 3 registries only exist for SolrCore registration. You could move them to the same package and make them not public.

But longer term (or soon if you are to do the work), I'd rather our built-in plugins be auto-discovered and registered via embracing java.util.ServiceLoader. Then we would have no static registries. -- CC @janhoy

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some tests outside the core package currently use these registries, including:

  • org.apache.solr.cloud.TestRandomFlRTGCloud (ref. transformers)
  • org.apache.solr.search.QueryEqualityTest (ref. value source parsers and query parser plugins)
  • org.apache.solr.search.TestStandardQParsers (ref. query parser plugins)
  • org.apache.solr.search.SignificantTermsQParserPluginTest (ref. query parser plugins)

From the logical grouping perspective it makes sense to me to keep them in the current packages. From the visibility perspective (public API) I would prefer to make them package-private / internal.

Perhaps its best to keep it as is for now until we introduce an auto-discovery feature?

@@ -398,7 +398,7 @@ protected ValueSource parseValueSource(int flags) throws SyntaxError {
if ((ch >= '0' && ch <= '9') || ch == '.' || ch == '+' || ch == '-') {
Number num = sp.getNumber();
if (num instanceof Long) {
valueSource = new ValueSourceParser.LongConstValueSource(num.longValue());
valueSource = new ValueSourceParsers.LongConstValueSource(num.longValue());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it appears inconsistent with the lower two lines; can you static import this? Or move to top level if the below ones are (consistency)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is actually interesting. The other two value sources are from Lucene, LongConstValueSource is from Solr, which is why this is inconsistent. I could add an import, but perhaps something else could be considered here?

Would ConstValueSource be the equivalent in Lucene for long values? Because I can only find ConstValueSource for double in Lucene.

* @deprecated Use {@link DocRouters#DEFAULT_NAME} instead.
*/
@Deprecated(since = "9.8", forRemoval = true)
public static final String DEFAULT_NAME = DocRouters.DEFAULT_NAME;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT about keeping this as a constant string? Then almost nobody would have a need to reference the new DocRouters.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered this an option, but thought that it would be better to keep DEFAULT (DocRouter) and DEFAULT_NAME (String) in the same class. So moving DEFAULT out would also affect DEFAULT_NAME.

Since I also moved out the getDocRouter(routerName) method, we still have a few more references to the new DocRouters. But perhaps that is also not necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeping getDocRouter(routerName) would probably be another case of class initialization deadlock, so I moved forward and removed the deprecation and kept DocRouters.DEFAULT_NAME, so that it aligns with the class reference of DocRouters.DEFAULT.


import java.util.Collections;

public class MapWriters {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just for EMPTY feels sad...
Instead, I could imagine MapWriter.empty() that references an EMPTY constant declared on MapWriterMap

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving EMPTY to MapWriterMap and providing a static MapWriter#empty() method looks like another possible case of ClassInitializationDeadlock. Allthough it is not identified by error-prone, I believe it is similar to the examples. But maybe I am wrong on that?

@malliaridis
Copy link
Contributor Author

Thanks for the review @dsmiley. I am not familiar enough with the modified classes to know which is cnosidered internal, so your input is very valuable to me. I generally try to follow the rule "anything that is public requires at least one major version of deprecation before removing it". But since it is considered internal, I will move forward and cleanup the deprecations. :)

Note that TransformerFactories is now immutable.
…ialization-deadlock

# Conflicts:
#	solr/solrj/src/test/org/apache/solr/client/solrj/impl/LBHttp2SolrClientIntegrationTest.java
@malliaridis malliaridis marked this pull request as ready for review December 1, 2024 14:52
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.

2 participants