Uploaded image for project: 'Geode'
  1. Geode
  2. GEODE-800

Geode's classloading mechanism is unable to resolve classes found within nested jars

    Details

      Description

      This issue is particularly evident when using Geode in a Spring Boot app which creates an '├╝ber' jar containing all dependent jars.

      When Geode is launched in this context, the following errors can be seen:

      [warn 2016/01/20 08:53:29.431 PST <main> tid=0xd] (tid=13 msgId=0) Required Commands classes were not loaded. Check logs for errors.
      java.lang.IllegalStateException: Required Commands classes were not loaded. Check logs for errors.
              at com.gemstone.gemfire.management.internal.cli.CommandManager.raiseExceptionIfEmpty(CommandManager.java:249)
              at com.gemstone.gemfire.management.internal.cli.CommandManager.loadCommands(CommandManager.java:188)
              at com.gemstone.gemfire.management.internal.cli.CommandManager.<init>(CommandManager.java:86)
              at com.gemstone.gemfire.management.internal.cli.CommandManager.getInstance(CommandManager.java:278)
              at com.gemstone.gemfire.management.internal.cli.CommandManager.getInstance(CommandManager.java:258)
              at com.gemstone.gemfire.management.internal.cli.remote.CommandProcessor.<init>(CommandProcessor.java:58)
              ...
      

      The problem here is in ClasspathScanLoadHelper.getClasses(). In this method we call:

      Enumeration<URL> resources = ClassPathLoader.getLatest().getResources(packagePath);
      

      However getResources() doesn't just work against the 'latest' classloader, but also considers the thread context classloader. In the case of a Spring Boot app, Spring does provide such a classloader and getResources is able to find the necessary resources CommandMarker classes. (These classes are found within a nested jar. For ex. jar:file:/Users/jdeppe/src/woddrive/WodDrive-GF-Server/target/WodDriveGFServer.jar!/lib/gemfire-core-1.0.0-incubating-SNAPSHOT.jar!/com/gemstone/gemfire/management/internal/cli/commands). This is all fine, but subsequent code doesn't consider classes (or packages) within nested jars, and in addition, when classes actually get resolved, the thread context classloader (where those resources might have come from) is not considered.

        Attachments

        1. geode-800-testcase.zip
          129 kB
          Francesco Foresti

          Issue Links

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                jens.deppe Jens Deppe
              • Votes:
                0 Vote for this issue
                Watchers:
                5 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:

                  Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0h
                  0h
                  Logged:
                  Time Spent - 0.5h
                  0.5h