I am not sure if my problem is a non-existent feature or I am using the neo4j-ogm framework incorrectly. Since you are only supposed to post bugs or feature requests in the projects GitHub repository, I would like to place my question here first.
Please be aware, that I shortened my real code to just give you an idea what I try to achieve.
My example application consists of two modules: Module a contains a class to create neo4j-ogm sessions. There I read the configuration from a property file and create the session factory, passing the packages to scan as parameters:
public Neo4jController(final String ... packagesWithNodes) {
ConfigurationSource props = new ClasspathConfigurationSource("neo4jogm.properties");
Configuration configuration = new Configuration.Builder(props).build();
SessionFactory sessionFactory = new SessionFactory(configuration, packagesWithNodes);
...
}
Module b includes module a as a Maven dependency and then tries to persist a NodeEntity
via the Session
object. The Session
is created correctly, but the NodeEntity
in the passed package is not recognized.
public MyObject create(final MyObject newObject) {
Neo4jController neo4jController = new Neo4jController("my.example.package");
neo4jController.getNeo4jSession().save(newObject);
...
}
This always results in an IllegalArgumentException
:
Class class my.example.package.MyObject is not a valid entity class. Please check the entity mapping.
This is what my NodeEntity
in module b looks like
package my.example.package;
import de.bitandgo.workflow.common.model.Neo4jNode;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Property;
@NodeEntity(label = "MyObject")
public class MyObject extends Neo4jNode {
@Property
public String name;
}
The base class contains among others
public abstract class Neo4jNode {
@Id
@GeneratedValue
private Long id;
}
I know that neo4j-ogm uses glassgraph internally for scanning the classpath. The corresponding call in the framework with prepended configuration looks like this:
private static List<String> useClassgraph(String[] packagesOrClasses) {
// .enableExternalClasses() is not needed, as the super classes are loaded anywhere when the class is loaded.
try (ScanResult scanResult = new ClassGraph()
.ignoreClassVisibility()
.acceptPackages(packagesOrClasses)
.acceptClasses(packagesOrClasses)
.scan()) {
return scanResult.getAllClasses().getNames();
}
}
Via debugging I verified that the desired package my.example.package
was passed as an argument to the GlassGraph
object.
Also the Neo4jController
in module a is able to load the class. I have tested this with the following code
try {
Class<?> aClass = Class.forName("my.example.package.MyObject");
System.out.println(aClass); // prints "class my.example.package.MyObject"
} catch (ClassNotFoundException e) {}
My question is whether neo4j-ogm/classgraph may not be able to find the class at all due to the way neo4j-ogm uses classgraph, or if I am doing something wrong in the usage.
Update 1:
The problem seems to be related to my application running inside an application server (TomEE). When I deploy my application ClassGraph is not able to find the configured package.
But executing the exact same scan via a classical main
method finds me the expected class.
public static void main(String[] args) {
try (ScanResult scanResult = new ClassGraph()
.ignoreClassVisibility()
.acceptPackages("my.example.package")
.acceptClasses()
.scan()) {
System.out.println(scanResult.getAllClasses().getNames());
}
}
So I assume the problem is related to the compiled classes not being visible in the "normal" classpath when deploying the application into an application server?
I appreciate any input.
Thanks a lot