首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >两个groovy类在自定义类加载器时相互导入导致循环编译错误。

两个groovy类在自定义类加载器时相互导入导致循环编译错误。
EN

Stack Overflow用户
提问于 2015-09-24 15:57:04
回答 1查看 143关注 0票数 0

我定制了Groovy类加载器,用于从文件系统中的目录加载类。

现在我有了groovy类,例如,

ICommentService.groovy

代码语言:javascript
复制
public interface ICommentService {
     public void a();
}

CommentService.groovy

代码语言:javascript
复制
public class CommentService implements ICommentService {
      public void a() {
          //doing something...
      }
}

IMomentService.groovy

代码语言:javascript
复制
public interface IMomentService {
     public void b();
}

MomentService.groovy

代码语言:javascript
复制
import ICommentService;
import CommentService;
public class MomentService implements IMomentService {
     public void b() {
         ICommentService commentService = new CommentService();
         commentService.a();

         //doing something
     }
}

我的定制类加载程序代码如下,

代码语言:javascript
复制
public class MyGroovyClassLoader extends GroovyClassLoader {
    private long version;
    private HashMap<String, ClassHolder> classCache;
    private HashSet<String> pendingGroovyClasses;

    public MyGroovyClassLoader(ClassLoader parentClassLoader,
            CompilerConfiguration cc) {
        super(parentClassLoader, cc);

        classCache = new HashMap<>();
    }

    public Class<?> parseGroovyClass(String key, File classFile)
            throws CoreException {
        ClassHolder holder =  classCache.get(key);
        if(holder != null && holder.getParsedClass() != null) {
            LoggerEx.info(TAG, "Load groovy class " + key
                    + " from cache");
            return holder.getParsedClass();
        }
        try {
            Class<?> parsedClass = parseClass(classFile);
            if (parsedClass != null) {
                holder = new ClassHolder();
                holder.parsedClass = parsedClass;
                classCache.put(key, holder);
            }
            LoggerEx.info(TAG, "Parse groovy class " + key
                    + " successfully");
            return parsedClass;
        } catch (Throwable e) {
            e.printStackTrace();
            throw new CoreException(
                    ChatErrorCodes.ERROR_GROOVY_PARSECLASS_FAILED,
                    "Parse class " + classFile + " failed, "
                            + e.getMessage());
        }
    }

    @Override
    public Class loadClass(String name, boolean lookupScriptFiles,
            boolean preferClassOverScript) throws ClassNotFoundException,
            CompilationFailedException {
        // TODO Auto-generated method stub
        Class<?> loadedClass = null;
        if(pendingGroovyClasses.contains(name)) {
            String key = name.replace(".", "/") + ".groovy";
            try {
                loadedClass = parseGroovyClass(key, new File(path + key));
                if(loadedClass != null)
                    return loadedClass;
            } catch (CoreException e) {
                e.printStackTrace();
                LoggerEx.error(TAG, "parse groovy class failed while load class, " + e.getMessage());
            }
        }

        try {
            loadedClass = super.loadClass(name, lookupScriptFiles,
                    preferClassOverScript);
        } catch (ClassNotFoundException e) {
        }

        return loadedClass;
    }

    public ClassHolder getClass(String classPath) {
        return classCache.get(classPath);
    }

    public long getVersion() {
        return version;
    }

    public String toString() {
        return MyGroovyClassLoader.class.getSimpleName() + "#" + version;
    }
}

现在,当我们在目录中解析那些groovy文件时。然后我们找到一个无限循环日志,如下所示,

代码语言:javascript
复制
Parse groovy class ICommentService.groovy successfully
Parse groovy class IMomentService.groovy successfully
Load groovy class ICommentService.groovy from cache
Load groovy class IMomentService.groovy from cache
Load groovy class ICommentService.groovy from cache
Load groovy class IMomentService.groovy from cache
Load groovy class ICommentService.groovy from cache
Load groovy class IMomentService.groovy from cache
Load groovy class ICommentService.groovy from cache
Load groovy class IMomentService.groovy from cache
Load groovy class ICommentService.groovy from cache
Load groovy class IMomentService.groovy from cache
Load groovy class ICommentService.groovy from cache
Load groovy class IMomentService.groovy from cache

问题是两个类是相互导入的,可以理解为什么会发生循环。但是java类加载器似乎可以很好地处理这个问题。那么我们如何在Groovy中解决这个问题呢?

请帮帮我!非常感谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-24 18:24:15

对于编译器为避免这个问题所做的内部查找,标志lookupScriptFiles是假的。与其覆盖loadClass,不如通过set/getResourceLoader使用GroovyResourceLoader或在GroovyClassLoader上覆盖getResource(String) (这个方法是从资源加载器调用的)。这样,编译器就能够自动查找源代码并将其添加到编译队列中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32765857

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档