DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Why "Polyglot Programming" or "Do It Yourself Programming Languages" or "Language Oriented Programming" sucks?
  • Getting Started With Agentic Workflows in Java and Quarkus
  • Building AI-Powered Java Applications With Jakarta EE and LangChain4j
  • Alternative Structured Concurrency

Trending

  • What Is Plagiarism? How to Avoid It and Cite Sources
  • GenAI Implementation Isn't Magic — It’s a Lifecycle
  • DevOps and Platform Engineering Readiness Checklist: Everything Needed for a Scalable, Secure, High-Velocity Delivery Platform
  • Stop Running Two Data Systems for One Agent Query
  1. DZone
  2. Coding
  3. Languages
  4. Class Loading Fun with Groovy

Class Loading Fun with Groovy

Sometimes you need special measures. Not to make Groovy work, but to make your applications or frameworks a little bit more powerful or versatile.

By 
Steven Devijver user avatar
Steven Devijver
·
Jan. 17, 08 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
42.9K Views

Join the DZone community and get the full member experience.

Join For Free

Sometimes you need special measures. Not to make Groovy work, but to make your applications or frameworks a little bit more powerful or versatile.

Here are two class loading techniques that I've used in combination with Groovy to make life more fun and interesting.

One: getting rid of Groovy

Sometimes you have to get hold of a ClassLoader that doesn't include the Groovy classes. Sometimes you need to have a ClassLoader that only contains the classes shipped with the JVM.

Every Java application has a ClassLoader that only contains JVM classes and you can get hold of it, if you know how.

The java.lang.ClassLoader class has a static getSystemClassLoader() method that returns a ClassLoader that contains all classes on the CLASSPATH when the JVM started:

ClassLoader.systemClassLoader.loadClass "some.class.on.the.ClassPath"

This ClassLoader has one or more parent ClassLoaders. The ClassLoader on top of this hierarchy is the one that only contains JVM classes. When you find a ClassLoader without parent you know you've found it:

def classLoader = ClassLoader.systemClassLoader
while (classLoader.parent) {
       classLoader = classLoader.parent
}

This little routine gets you the top ClassLoader. You can now use this one to create a new ClassLoader hierarchy. It only takes creating a new URLClassLoader and provide the locations of the JAR files you want to include:

def classLoader = ClassLoader.systemClassLoader
while (classLoader.parent) {
classLoader = classLoader.parent
}
def newClassLoader = new URLClassLoader([new File("location/to.jar").toString().toURL()] as URL[], classLoader)

You now have a new ClassLoader. Warning: it does not include Groovy if you don't add the Groovy JAR specifically, and any classes that have already been loaded will be loaded again, increasing the memory foot-print of your application. Also, don't create too many new ClassLoaders in one application since they tend to cause memory leaks. Creating one or a few should be fine. Classes loaded with the new ClassLoader will not be compatible with classes loaded by the current system ClassLoader, except for the JVM classes.

You can improve this code by using the org.apache.tools.ant.launch.Locator class (that ships with Ant). Its fileToURL() method does a slightly better job at converting java.io.File objects to java.net.URL methods.

Two: getting hold of GroovyClassLoader in Java code

Sometimes you have to get hold of a groovy.lang.GroovyClassLoader object in Java code. This may for example happen when Java code is called from Groovy code. GroovyClassLoaders tend the be at the bottom of ClassLoader hierarchies, and sometimes you want to load classes in GroovyClassLoader and not anywhere else in the ClassLoader hierarchy.

Your Java code however was most likely not loaded by the GroovyClassLoader, so how to get hold of it? You could pass is explicitly from your Groovy code but that's not practical. Instead, use the sun.reflect.Reflection class? Never heard of it? Then it's time to meet the getCallerClass() method.

When Groovy code calls Java code then somewhere up in the stack there is a Groovy class that's been loaded by a GroovyClassLoader. Here's how to get hold of it from Java code:

import sun.reflect.Reflection;
import groovy.lang.GroovyClassLoader;
public class MyClass {
public void myMethod() throws Exception {
int frame = 1;
// number of levels above you in the stack
Class c = Reflection.getCallerClass(frame); 
while (c != null && !(c.getClassLoader() instanceof GroovyClassLoader)) {
frame++;
c = Reflection.getCallerClass(frame);
}
if (c != null) {
GroovyClassLoader gcl = (GroovyClassLoader) c.getClassLoader();
// do Groovy stuff here
Class newClass = gcl.parseClass("class MyNewClass{}");
}       
}
}

These tricks show just how much Groovy is integrated with the JVM, and how Groovy generates proper Java byte-code.

Happy Groovy coding!

Groovy (programming language) Java (programming language)

Opinions expressed by DZone contributors are their own.

Related

  • Why "Polyglot Programming" or "Do It Yourself Programming Languages" or "Language Oriented Programming" sucks?
  • Getting Started With Agentic Workflows in Java and Quarkus
  • Building AI-Powered Java Applications With Jakarta EE and LangChain4j
  • Alternative Structured Concurrency

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook