gpt4 book ai didi

java - 自定义类加载器时,两个groovy类相互导入导致循环编译错误

转载 作者:行者123 更新时间:2023-12-01 11:07:41 25 4
gpt4 key购买 nike

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

现在我有下面的常规类(class),

ICommentService.groovy

public interface ICommentService {
public void a();
}

CommentService.groovy

public class CommentService implements ICommentService {
public void a() {
//doing something...
}
}

IMomentService.groovy

public interface IMomentService {
public void b();
}

MomentService.groovy

import ICommentService;
import CommentService;
public class MomentService implements IMomentService {
public void b() {
ICommentService commentService = new CommentService();
commentService.a();

//doing something
}
}

我的自定义类加载器代码如下,

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;
}
}

现在,当我们解析目录中的那些常规文件时。然后我们发现了一个无限循环日志如下,

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 中我们如何解决这个问题呢?

请帮忙!非常感谢!

最佳答案

对于编译器执行的内部查找,标志lookupScriptFiles 为 false,以避免出现此问题。您应该通过 set/getResourceLoader 使用 GroovyResourceLoader 或覆盖 GroovyClassLoader 上的 getResource(String) (此方法是从资源中调用的),而不是覆盖 loadClass装载机)。这样编译器将能够自行查找源代码并将其自动添加到编译队列中。

关于java - 自定义类加载器时,两个groovy类相互导入导致循环编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32765857/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com