You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Sometimes (occasional) when starting my Spring Boot 2.1.1 application (included is OGM 3.1.5, bolt driver), a NullPointerException occurs with stack trace:
Caused by: java.lang.NullPointerException: null
at org.neo4j.ogm.drivers.bolt.request.BoltRequest.executeRequest(BoltRequest.java:149) ~[neo4j-ogm-bolt-driver-3.1.5.jar:3.1.5]
at org.neo4j.ogm.drivers.bolt.request.BoltRequest.execute(BoltRequest.java:143) ~[neo4j-ogm-bolt-driver-3.1.5.jar:3.1.5]
at org.neo4j.ogm.session.delegates.ExecuteQueriesDelegate.lambda$query$0(ExecuteQueriesDelegate.java:102) ~[neo4j-ogm-core-3.1.5.jar:3.1.5]
at org.neo4j.ogm.session.Neo4jSession.doInTransaction(Neo4jSession.java:569) ~[neo4j-ogm-core-3.1.5.jar:3.1.5]
at org.neo4j.ogm.session.Neo4jSession.doInTransaction(Neo4jSession.java:553) ~[neo4j-ogm-core-3.1.5.jar:3.1.5]
at org.neo4j.ogm.session.delegates.ExecuteQueriesDelegate.query(ExecuteQueriesDelegate.java:100) ~[neo4j-ogm-core-3.1.5.jar:3.1.5]
at org.neo4j.ogm.session.delegates.ExecuteQueriesDelegate.query(ExecuteQueriesDelegate.java:80) ~[neo4j-ogm-core-3.1.5.jar:3.1.5]
at org.neo4j.ogm.session.Neo4jSession.query(Neo4jSession.java:413) ~[neo4j-ogm-core-3.1.5.jar:3.1.5]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.data.neo4j.transaction.SharedSessionCreator$SharedSessionInvocationHandler.invoke(SharedSessionCreator.java:122) ~[spring-data-neo4j-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at com.sun.proxy.$Proxy146.query(Unknown Source) ~[na:na]
It happens unpredictable which is already a pointer to a multi-thread issue.
Possible Solution
I debugged into it and "cypherModification" is null when the NPE is thrown. The problematic code seems to be the lazy initialization:
Looks like a double-checked locking (https://en.wikipedia.org/wiki/Double-checked_locking) but isn't correctly done. Assume that 2 threads arrived at the synchronized block at the same time. One of them wins, loads the cypher modifications, sets it to the local variable and returns it. The 2nd thread, however, enters then the synchronized block and detects that "cypherModification" is not null and hence, does not do anything there. The local variable "loadedCypherModification" is still null and will be returned.
In Wikipedia, there is an example:
// Works with acquire/release semantics for volatile in Java 1.5 and later
// Broken under Java 1.4 and earlier semantics for volatile
class Foo {
private volatile Helper helper;
public Helper getHelper() {
Helper localRef = helper;
if (localRef == null) {
synchronized (this) {
localRef = helper; // <------ missing in ogm code
if (localRef == null) {
helper = localRef = new Helper();
}
}
}
return localRef;
}
// other functions and members...
}
I think a loadedCypherModification = this.cypherModification as first line of the synchronized block would be sufficient to fix the problem.
Steps to Reproduce (for bugs)
Due to its occasional occurence, it is hard to reproduce.
Context
Your Environment
OGM Version used: 3.1.5
Java Version used: 11
Neo4J Version used: 3.5.0
Bolt Driver Version used (if applicable): 3.1.5
Operating System and Version: Windows 10
Link to your project:
The text was updated successfully, but these errors were encountered:
Expected Behavior
Expecting to always start without null pointer.
Current Behavior
Sometimes (occasional) when starting my Spring Boot 2.1.1 application (included is OGM 3.1.5, bolt driver), a NullPointerException occurs with stack trace:
It happens unpredictable which is already a pointer to a multi-thread issue.
Possible Solution
I debugged into it and "cypherModification" is null when the NPE is thrown. The problematic code seems to be the lazy initialization:
Looks like a double-checked locking (https://en.wikipedia.org/wiki/Double-checked_locking) but isn't correctly done. Assume that 2 threads arrived at the synchronized block at the same time. One of them wins, loads the cypher modifications, sets it to the local variable and returns it. The 2nd thread, however, enters then the synchronized block and detects that "cypherModification" is not null and hence, does not do anything there. The local variable "loadedCypherModification" is still null and will be returned.
In Wikipedia, there is an example:
I think a
loadedCypherModification = this.cypherModification
as first line of the synchronized block would be sufficient to fix the problem.Steps to Reproduce (for bugs)
Due to its occasional occurence, it is hard to reproduce.
Context
Your Environment
The text was updated successfully, but these errors were encountered: