Skip to content

Conversation

meistermeier
Copy link
Contributor

Upgrading the Neo4j Java driver to the next major version requires some changes:

  • Remove JCL helper (not needed anymore)
  • Adding dependency on the Neo4j Java driver's observation module for micrometer to support the new metric reporting system
  • minor changes regarding scheme API checks

My build setup (and general Gradle) knowledge is pretty limited and I am not sure how to make use of the Java driver BOM (https://central.sonatype.com/artifact/org.neo4j.driver/neo4j-java-driver-bom) here. Given the fact that there is already the alignment definition for Spring Data Neo4j in the dependency definition.

I couldn't find any micrometer tests with Neo4j and was not sure if this is needed and/or where to place them correctly.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Oct 2, 2025
@snicoll
Copy link
Member

snicoll commented Oct 2, 2025

Thanks for the PR. Is that a mandatory requirement for the next RC of Spring Data?

My build setup (and general Gradle) knowledge is pretty limited and I am not sure how to make use of the Java driver BOM

FTR we can't use the BOM as it isn't one. It provides dependency management for Netty and it should not as a BOM should only provide dependency management for the dependencies of the project itself.

@snicoll snicoll changed the title Upgrade Neo4j Java driver to 6.0.0. Upgrade to Neo4j Java Driver 6.0.0 Oct 2, 2025
Signed-off-by: Gerrit Meier <[email protected]>
@meistermeier
Copy link
Contributor Author

Is that a mandatory requirement for the next RC of Spring Data?

We merged the 6.0 driver upgrade in SDN to the main branch (next RC) this morning and as a supportive downstream developer, I raised this timely ;)

It provides dependency management for Netty and it should not as a BOM should only provide dependency management for the dependencies of the project itself

Thanks for looking into this, missed the definition there.

@michael-simons
Copy link
Contributor

Hey @snicoll see neo4j/neo4j-java-driver#1707 from our colleague.

We had been unsure while adding it, the Maven manually is not 100% clear on this, at least there's nothing saying "you must not include dependencies"

We would love to hear your experience on that topic, though.

Please let us know if the declaration @meistermeier created in the Gradle file is enough or if we must change this before the PR can go in. Thank you.

Signed-off-by: Gerrit Meier <[email protected]>
@meistermeier
Copy link
Contributor Author

For sure I ran the wrong build locally, should be better now.

> Task :platform:spring-boot-dependencies:bomrCheck FAILED

Neo4j Java Driver
    - Version 6.0.0 is misaligned. It should be 5.28.9.

fails now but I assume that is due to Spring Boot checking Spring Data Neo4j's version definition from a milestone branch instead of latest main.

@snicoll
Copy link
Member

snicoll commented Oct 2, 2025

see neo4j/neo4j-java-driver#1707 from our colleague.

Very cool, thank you!

the Maven manually is not 100% clear on this,

I bet it isn't. They can't make such a strong stance but we can. Or rather, we can decide not to include a BOM that does not match that expectation.

The main idea is that if you have two sources of dependency management for the same artifact, it can lead to various issues (inconsistencies, warning in Maven itself, etc). Neo4J isn't at the application layer, it is a driver/library. As such, it should not have an opinion on the exact version of Netty that users should consume. If that is necessary, then shading is the right option.

@snicoll
Copy link
Member

snicoll commented Oct 2, 2025

fails now but I assume that is due to Spring Boot checking Spring Data Neo4j's version definition from a milestone branch instead of latest main.

Yes. I think you should migrate to Spring Data snapshot in your PR. It's a bit odd that you migrate to the new driver whilst Spring Data Neo4J isn't upgraded. Actually, I am surprised that it even works...

@michael-simons
Copy link
Contributor

I bet it isn't. They can't make such a strong stance but we can. Or rather, we can decide not to include a BOM that does not match that expectation.

Thanks @snicoll This makes sense and we will fix that in the next release. The intention behind was this: The latest driver can use native transport, such as epoll, io_uring etc. We wanted to help application builders and picking the right versions of the than required additional dependencies without having to search for them. But on the other hand, I think it's fair to assume quite technical users in that area that are aware that there's a bom for that. We also update our manual on that topic. Cheers.

@snicoll snicoll added type: dependency-upgrade A dependency upgrade and removed status: waiting-for-triage An issue we've not yet triaged labels Oct 3, 2025
@snicoll snicoll added this to the 4.0.0-RC1 milestone Oct 3, 2025
@snicoll snicoll self-assigned this Oct 3, 2025
snicoll pushed a commit to snicoll/spring-boot that referenced this pull request Oct 3, 2025
snicoll added a commit to snicoll/spring-boot that referenced this pull request Oct 3, 2025
Copy link
Member

@snicoll snicoll left a comment

Choose a reason for hiding this comment

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

Tanks for the PR. I've started to polish in https://github.com/snicoll/spring-boot/tree/pr/47381

There's no need to push any further change. I've added a few comments and could use your insights when you have a min.

Driver neo4jDriver(Neo4jProperties properties, Environment environment, Neo4jConnectionDetails connectionDetails,
ObjectProvider<ConfigBuilderCustomizer> configBuilderCustomizers) {
ObjectProvider<ConfigBuilderCustomizer> configBuilderCustomizers,
ObjectProvider<ObservationRegistry> observationRegistryProvider) {
Copy link
Member

Choose a reason for hiding this comment

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

We can't do this here. If we did then we could not configure a Neo4j driver without the observation registry on the classpath.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Michael already answered the most bits. I think the approach with your ConfigBuilderCustomiser makes most sense. Thanks for putting the effort in to take it over the line ;)

builder.withMaxConnectionLifetime(pool.getMaxConnectionLifetime().toMillis(), TimeUnit.MILLISECONDS);
builder.withConnectionAcquisitionTimeout(pool.getConnectionAcquisitionTimeout().toMillis(),
TimeUnit.MILLISECONDS);
if (pool.isMetricsEnabled()) {
Copy link
Member

Choose a reason for hiding this comment

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

I am not sure I like that change. If metrics vs. no metrics is no longer needed, then I think the metricsEnabled flag should go away and have metrics to be exported if an ObservationRegistry is available. That's what the other components are doing at the moment.

Is there a reason to keep having a flag for this or was it just an attempt at migrating what we had before?

Copy link
Contributor

Choose a reason for hiding this comment

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

The latter.

Copy link
Member

Choose a reason for hiding this comment

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

OK cool, Let me remove the flag then.

Scheme.validateScheme(lowerCaseScheme);
}
catch (IllegalArgumentException ex) {
if (!ServiceLoader.load(BoltConnectionProviderFactory.class)
Copy link
Member

Choose a reason for hiding this comment

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

That's quite a bit of ceremony here. Do we really need to invoke "any" factory this way? Also this adds an import on BoltConnectionProviderFactory...

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, that's the way the drivers team designed that. Maybe Gerrit has a better idea working around it, I don't have one.

Copy link
Member

@snicoll snicoll Oct 6, 2025

Choose a reason for hiding this comment

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

Where can I read more about this? I am confused about any such factory to provide the answer...

Copy link
Contributor

Choose a reason for hiding this comment

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

@injectives Can you please chime in here? In the code in question we want to validate the scheme of the URI provided by a user through configuration. We used to be able to do this via Scheme of the driver, but can't anymore, as it depends now on what bolt implementations are on the class/module path. Did the drivers team think about a different solution than what Gerrit and I suggested here? Thank you very much in advance.

Choose a reason for hiding this comment

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

To be honest, I wasn't aware of such need. Therefore, the official drivers don't really offer such option.

However, one way of checking if the driver would actually support a given scheme in a specific deployment would be to try creating one:

GraphDatabase.driver("scheme://localhost", AuthTokens.none());

If the scheme is not supported, it throws:

java.lang.IllegalArgumentException: Unsupported scheme: scheme

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for following up! I am not keen to do that, this relies on an implementation detail and has a scope much broader than what we're trying to determine.

@michael-simons given the feedback above, perhaps we should stop validating the scheme upfront? I don't want to support something that the driver doesn't really expect. Unless I am missing something?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Then we leave it to the driver. Please remove this bit from the autoconfig 🙏 It also makes it less complex, what should be the goal for the config and its maintenance.

Choose a reason for hiding this comment

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

Ah, one more option. Similar to the previous implementation in a sense that it is also using internal driver classes:

var loader = new BoltConnectionProviderFactoryLoader(Logging.none(), URI.create("scheme://localhost"));
loader.providerFactory().isPresent(); // true if supported

Obviously, this is not a public API.

@snicoll snicoll added the status: waiting-for-feedback We need additional information before we can continue label Oct 3, 2025
@snicoll snicoll changed the title Upgrade to Neo4j Java Driver 6.0.0 Update Neo4j support to require Neo4j Java Driver 6.0.0 Oct 3, 2025
@snicoll snicoll added type: enhancement A general enhancement and removed type: dependency-upgrade A dependency upgrade labels Oct 3, 2025
@snicoll
Copy link
Member

snicoll commented Oct 3, 2025

I've also switched this PR to an enhancement as it isn't "just" a dependency upgrade.

snicoll pushed a commit to snicoll/spring-boot that referenced this pull request Oct 6, 2025
snicoll added a commit to snicoll/spring-boot that referenced this pull request Oct 6, 2025
@snicoll snicoll removed the status: waiting-for-feedback We need additional information before we can continue label Oct 7, 2025
snicoll pushed a commit that referenced this pull request Oct 7, 2025
snicoll added a commit that referenced this pull request Oct 7, 2025
@snicoll snicoll closed this in c2e838a Oct 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants