I have been looking in to the behavior of loading classes that have been deployed. When the jar is deployed, the server blindly loads the classes, searching for Geode Functions. Specifically, walks over the classes in the jar, loads each one, and checks to see if both Function and Declarable are implemented.
Because there's nothing done to limit the classes loaded, this can create a Class Loader leak, causing an OutOfMemoryException: PermGem (or, now with java 1.8, OutOfMemoryException: Metaspace) I wanted to experiment with the behavior, so I grabbed a copy of an OpenSource project (openhtmltopdf) and wrapped it in to a function I could call via the dev REST API. Basically, when the function is called, it'll read in a simple html document and produce a simple PDF from it. The project has several dependencies, which created the first problem. It was necessary to explode both openhtmltopdf-core.jar and openhtmltopdf-pdfbox.jar out in to my Function's jar. However, there are also external Apache jars that are required: - pdfbox-2.0.3.jar - fontbox-2.0.3.jar - commons-logging-1.2.jar If I create an über.jar that contains all of these dependencies and my Function, then deploy it, I'm able to execute my Function without any problems. If I make a small change to the loader to accept a pattern to only actually load my Function class out of the jar, the rest of the classes are not automatically loaded. This causes ClassNotFound and ClassDefNotFound exceptions. If I start my sever and provide the 3 Apache libraries with the --classpath option, and have my jar only contain my Function and the openhtmltopdf project classes, then when I deploy I'm able to run my function. Are there any other scenarios to try out to let the class loader load what's needed rather than having to build these uber jars or specify dependencies on the server classpath at startup? I don't know of any way to dynamically update the classpath once the server is up and running.