Skip to content

Call to classgraph inside JAX-RS endpoint does not find any results #515

@Restage

Description

@Restage

Hi,

I’ve started a small project in which I use the neo4j-ogm library, which itself uses classgraph to find relevant entity classes.
Since this application was never able to find any of my entities, no matter in which package they reside, I did some research to find the root cause of the problem.

In the end I discovered that using classgraph inside a servlet works perfect.

@WebServlet(name = "TestServlet", urlPatterns = "/servlet")
public class TestServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try (ScanResult scanResult =
                     new ClassGraph()
                             .verbose()               // Log to stderr
                             .enableAllInfo()         // Scan classes, methods, fields, annotations
                             .acceptPackages("de.test.classgraph")
                             .scan()) {               // Start the scan
            for(String name : scanResult.getAllClasses().getNames()) {
                resp.getOutputStream().println(name);
            }
        }

        resp.setStatus(HttpServletResponse.SC_OK);
    }
}

I got de.test.classgraph.ClassToFind as the expected result.

But as soon as I put the same code inside a JAX-RS endpoint classgraph fails to find my class.

@Path("/rest")
public class TestRest {
    @GET
    public Response ping() {
        String allClasses = "";

        try (ScanResult scanResult =
                     new ClassGraph()
                             .verbose()               // Log to stderr
                             .enableAllInfo()         // Scan classes, methods, fields, annotations
                             .acceptPackages("de.bitandgo.classgraph")
                             .scan()) {               // Start the scan
            for(String name : scanResult.getAllClasses().getNames()) {
                allClasses += name + "\n";
            }
        }

        return Response.ok().entity(allClasses).build();
    }
}

The application with both endpoints has been deployed on apache-tomee-webprofile-8.0.6.

I then took a look at the classgraph log output and discovered that different classloaders where used.
Calling the servlet brought

ClassGraph	---- Found ClassLoaders:
ClassGraph	------ org.apache.tomee.catalina.TomEEWebappClassLoader
ClassGraph	------ sun.misc.Launcher$AppClassLoader
ClassGraph	------ java.net.URLClassLoader

while accessing the JAX-RS endpoint gave me

ClassGraph	---- Found ClassLoaders:
ClassGraph	------ org.apache.openejb.server.cxf.transport.util.CxfContainerClassLoader
ClassGraph	------ sun.misc.Launcher$AppClassLoader
ClassGraph	------ java.net.URLClassLoader

So I was hoping that overriding the classloader might give me the expected result. But enhancing the configuration to

new ClassGraph()
    .verbose()               // Log to stderr
    .enableAllInfo()         // Scan classes, methods, fields, annotations
    .acceptPackages("de.test.classgraph")
    .overrideClassLoaders(new TomEEWebappClassLoader())
    .scan())

didn't find the class either.

This repository contains the full example.

So is this a bug or am I doing something wrong?

Best regards

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions