Boot-Class-Path配置目录无效

本文探讨了JavaAgent中Boot-Class-Path配置仅支持文件而非目录的问题,通过源码分析揭示了这一限制的原因,并指出官方文档描述与实际行为之间的不一致。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文作者:suxingrui
本文链接:https://blog.youkuaiyun.com/suxingrui/article/details/80114768
版权声明:本文为原创文章,转载请注明出处。

如题,在使用Java Agent过程中发现,agent JAR文件定义的manifest属性中的Boot-Class-Path配置成目录时无效。

虽然官方说明是支持目录的:
Boot-Class-Path
A list of paths to be searched by the bootstrap class loader. Paths represent directories or libraries (commonly referred to as JAR or zip libraries on many platforms). …详见

但尝试多次之后发现,确实无效。追踪溯源,只能去怼源码,顺便记录下调查过程。


调查基于JDK8、JDK8、JDK8!

InvocationAdapter.c

JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM *vm, char *tail, void * reserved) {// agent加载入口
        ...
        /*
         * If the Boot-Class-Path attribute is specified then we process
         * each relative URL and add it to the bootclasspath.
         */
        bootClassPath = getAttribute(attributes, "Boot-Class-Path");
        if (bootClassPath != NULL) {
            appendBootClassPath(agent, jarfile, bootClassPath);
        }
        ...
}

static void
appendBootClassPath( JPLISAgent* agent,
                     const char* jarfile,
                     const char* pathList ) {
           ...
           // 循环遍历path:pathList,查找path下的jar文件,添加到bootstrap class loader
           jvmtierr = (*jvmtienv)->AddToBootstrapClassLoaderSearch(jvmtienv, path);
           ...
}

jvmtiEnv.cpp

jvmtiError
JvmtiEnv::AddToBootstrapClassLoaderSearch(const char* segment) {// 查找实现
    ...
    // create the zip entry
    ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment);
    if (zip_entry == NULL) {
      return JVMTI_ERROR_ILLEGAL_ARGUMENT;
    }
    ...
} /* end AddToBootstrapClassLoaderSearch */

classLoader.cpp

// Create a class path zip entry for a given path (return NULL if not found
// or zip/JAR file cannot be opened)
ClassPathZipEntry* ClassLoader::create_class_path_zip_entry(const char *path) {
  // check for a regular file
  struct stat st;
  if (os::stat(path, &st) == 0) {
    if ((st.st_mode & S_IFREG) == S_IFREG) {// S_IFREG 表示一般文件
      ...
    }
  }
  return NULL;
}

嗯,很好。只支持文件!

刚好看到create_class_path_zip_entry方法上面的create_class_path_entry(应该对应的是Class-Path的配置,待查)
包含以下逻辑

  } else {
    // Directory
    new_entry = new ClassPathDirEntry(path);
    if (TraceClassLoading) {
      tty->print_cr("[Path %s]", path);
    }
  }

所以呢,官方也有好些坑等人去填。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值