gpt4 book ai didi

java - 如何通过阅读代码确定 Java 源代码的所有运行时(但不是静态)依赖项?

转载 作者:搜寻专家 更新时间:2023-10-31 20:00:04 25 4
gpt4 key购买 nike

假设我想断言给定的 Java 源文件夹包含运行源文件夹中包含的任何程序所需的所有源代码。仅仅显示整个源文件夹编译是不够的,因为可能其中一些程序使用反射来实例化对象。因此,我可以搜索所有代码并查找 newInstance() 的调用,以了解哪些类预计会在运行时出现。但是对 Class.forName(...) 的调用不涉及对 newInstance() 的调用呢?最好也检查一下。但是我需要检查多少这样的东西?

是否有任何类型的详尽列表可供我引用,以确保我正在考虑 Java 中可以引入此类运行时依赖项的每种方式?重申一下,是否存在一些操作列表,如果我不能显示源文件夹中的任何源代码,则使用那些操作(并且该文件夹编译)所有(代码)依赖项都存在?

如果不存在这样的列表,我们是否可以在此线程中启动一个并尽最大努力涵盖我们知道的所有操作?

编辑

我想缩小问题的范围。我最想展示的是,如果代码库编译通过,则所有依赖项都存在。在我看来,要做到这一点,我需要先编译代码库,然后检查是否有任何代码调用了某些可能引入运行时依赖性的方法(例如 newInstance)。如果没有找到这样的方法,我有理由相信所有必需的代码都以源代码形式存在,并且运行该程序不会生成 ClassNotFoundException

最佳答案

原始问题的答案

据我所知,没有广泛的方法可以做到这一点。我的意思是考虑以下代码:

public static Object calleableFromAnywhere(Object o) throws IllegalAccessException, InstantiationException {
Object ret = null;
if(!Objects.isNull(o)){
ret = o.getClass().newInstance();
}
return ret;
}

在这种情况下,你甚至不知道在运行时你会有什么样的依赖。

如果您将搜索限制为仅基于构造函数的对象创建,您还有很多选择:

Constructor<?> constructor = o.getClass().getConstructor();
//there could be a lot of constructors enclosing different paramethers

Object something = o.getClass().newInstance();
//default constructor called

甚至那些都可以通过反射获得……兔子洞是无限深的。

您提到的 Class.forName(...) 调用可以采用任何参数 String 并且这些参数可以从数据库或用户的输入字段中给出。

我认为不可能预测您在运行时可能遇到的所有 String 变量。如果你有这样的事情,你不太可能成功。

TL.DR.: 据我所知,没有确切的解决方案。根据问题,您不仅对 newInstance 或实例创建感兴趣,因为您还可以将类的静态方法作为依赖项。这个想法很好,但是这个问题没有 100% 的解决方案。

缩小/澄清问题的答案

newInstance 调用没有引入新的依赖项。它只能在加载的类定义上调用。 (基本上,如果类无法加载,您永远不会到达 newInstance。)因此,如果您的目标是高度确定地回答,如果类不会被表示是另一个问题。

改变前面的例子表明你不太可能有定义的依赖类:

public static Class getClass(String name) throws ClassNotFoundException {
return Class.forName(name);
}

因为 name 可以是您可以在运行时收到的任何内容。还有其他加载类的方法,如下例所示。

public Class getClassExample1(String name) throws ClassNotFoundException {
return this.getClass().getClassLoader().loadClass(name);
}

根据 ClassNotFoundException 异常的 JavaDoc,这些地方正在使用它:

  • @see java.lang.Class#forName(java.lang.String)
  • @see java.lang.ClassLoader#findSystemClass(java.lang.String)
  • @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)

那些是它被抛出的地方,但是你必须检查那些方法的每条路径,比如 someInstance.getClass(name)

除了运行时依赖你还可能遇到NoClassDefFoundError。如果您正在使用一些容器并设置一些依赖项,例如在 maven 中提供的,您也可能在运行时遇到一些问题,而编译完全没问题。

TL.DR.V2:您只能通过静态分析将不存在依赖关系的风险降至最低,但如果您想尝试它,您应该检查提到的方法和所有调用可能导致这些的链(甚至通过反射)。

关于java - 如何通过阅读代码确定 Java 源代码的所有运行时(但不是静态)依赖项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44123536/

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