Java Groovy扩展模块方法-无方法签名

Java Groovy扩展模块方法-无方法签名,java,gradle,groovy,jar,urlclassloader,Java,Gradle,Groovy,Jar,Urlclassloader,我在java.util.ArrayList()上创建了两个groovy扩展模块/方法。它在我的IDE中运行得非常好。我使用gradle构建jar,并将其部署到远程JVM。当它到达远程JVM时,它会失败 以下是扩展方法: static Map sumSelectedAttributes(final List self, List attributes) { Map resultsMap = [:] attributes.each { attr -> r

我在
java.util.ArrayList()
上创建了两个groovy扩展模块/方法。它在我的IDE中运行得非常好。我使用
gradle
构建jar,并将其部署到远程
JVM
。当它到达远程
JVM
时,它会失败

以下是扩展方法:

    static Map sumSelectedAttributes(final List self, List attributes) {
    Map resultsMap = [:]
    attributes.each { attr ->
        resultsMap[attr] = self.inject(0) { sum, obj ->
            sum + obj[attr]
        }
    }
    return resultsMap
下面是调用它的代码:

outputMap[processName][iName] << kBeanList.sumSelectedAttributes([
    "messageCount", "userCount", "outstandingRequests",
    "cpuUsage", "memoryUsage", "threadCount", "cacheCount", "huserCount",
    "manualHuserCount", "dataPointerCount", "tableHandleCount",
    "jdbCacheRecordCount", "dbConnectionCount"])

outputMap[processName][iName]要手动注册扩展方法模块,可以使用与Grapevy中使用的代码类似的代码。因为grapes也有同样的问题,它们使jar在错误的加载程序中可见,但仍然希望启用扩展方法。这里讨论的代码如下:

JarFile jar = new JarFile(file)
def entry = jar.getEntry(ExtensionModuleScanner.MODULE_META_INF_FILE)
if (entry) {
  Properties props = new Properties()
  props.load(jar.getInputStream(entry))
  Map<CachedClass, List<MetaMethod>> metaMethods = new HashMap<CachedClass, List<MetaMethod>>()
  mcRegistry.registerExtensionModuleFromProperties(props, loader, metaMethods)
  // add old methods to the map
  metaMethods.each { CachedClass c, List<MetaMethod> methods ->
    // GROOVY-5543: if a module was loaded using grab, there are chances that subclasses
    // have their own ClassInfo, and we must change them as well!
    Set<CachedClass> classesToBeUpdated = [c]
    ClassInfo.onAllClassInfo { ClassInfo info ->
      if (c.theClass.isAssignableFrom(info.cachedClass.theClass)) {
        classesToBeUpdated << info.cachedClass
      }
    }
    classesToBeUpdated*.addNewMopMethods(methods)
  }
}
JarFile jar=新的JarFile(文件)
def entry=jar.getEntry(ExtensionModuleScanner.MODULE\u META\u INF\u文件)
如果(条目){
Properties props=新属性()
加载(jar.getInputStream(条目))
Map metaMethods=newhashmap()
registerExtensionModuleFromProperties(道具、加载器、元方法)
//将旧方法添加到映射中
metaMethods.each{CachedClass c,列出方法->
//GROOVY-5543:如果模块是使用grab加载的,那么子类很可能
//拥有自己的ClassInfo,我们也必须更改它们!
Set classesToBeUpdated=[c]
ClassInfo.onalClassInfo{ClassInfo信息->
if(c.theClass.isAssignableFrom(info.cachedClass.theClass)){

classesToBeUpdated当您说custom class loader时,它会发出警报;)一般来说,Groovy要能够加载扩展模块,Groovy运行时的加载程序必须能够看到该模块。这与您的应用程序通常的工作方式不同,在那里,应用程序类加载程序需要看到运行时,但运行时可以看到es看不到应用程序类。因此,我现在当然想知道您在远程JVM上的实际类加载设置。感谢您的响应,听起来您已经立即发现了问题。在这种情况下,是否根本不可能使用扩展模块。根据我的代码,您能推荐一些替代方法吗?我有点像p围绕这一点设计了大量代码。为了确认这一点,为了子孙后代,我刚刚在原始文章中添加了“classloader类”供您审阅。它位于开发框中,我们需要同时加载不同版本的JAR,并且需要在不重新启动JVM的情况下灵活加载更改。(dev/test/prod分支).哇,我不相信会有这样的解决方案。我真的很感谢您的洞察力和信息!仅供参考,因为其他人的支持能力是一个相当大的因素,我决定将功能移动到某个特性,并在需要的地方实现它会更简单。这花了整整20分钟…groovy的强大功能和灵活性!
JarFile jar = new JarFile(file)
def entry = jar.getEntry(ExtensionModuleScanner.MODULE_META_INF_FILE)
if (entry) {
  Properties props = new Properties()
  props.load(jar.getInputStream(entry))
  Map<CachedClass, List<MetaMethod>> metaMethods = new HashMap<CachedClass, List<MetaMethod>>()
  mcRegistry.registerExtensionModuleFromProperties(props, loader, metaMethods)
  // add old methods to the map
  metaMethods.each { CachedClass c, List<MetaMethod> methods ->
    // GROOVY-5543: if a module was loaded using grab, there are chances that subclasses
    // have their own ClassInfo, and we must change them as well!
    Set<CachedClass> classesToBeUpdated = [c]
    ClassInfo.onAllClassInfo { ClassInfo info ->
      if (c.theClass.isAssignableFrom(info.cachedClass.theClass)) {
        classesToBeUpdated << info.cachedClass
      }
    }
    classesToBeUpdated*.addNewMopMethods(methods)
  }
}