我可以在已编译的Java项目中替换类文件吗?

时间:2012-05-07 09:34:28

标签: java

这可能而且应该是一个已被多次询问和回答的问题,但我无法找到答案。

如果我在服务器上运行已编译的应用程序,我是否可以在本地计算机上编译应用程序,并将我在本地计算机上编译的类与服务器上的类交换?

换句话说,我是否可以替换已编译且位于服务器端的文件,文件几乎相同,已编译并位于我的本地计算机上?< / p>

由于服务器端的版本在其他文件中有一些硬编码连接,而且我不知道所有的地方,我宁愿只交换我需要的一个文件,而不是为应用程序重新编译作为一个整体。

3 个答案:

答案 0 :(得分:3)

您的问题的答案是肯定的,您可以替换类文件,但它有点复杂,因为您必须确保没有其他依赖项发生更改。

例如,如果要编译的类涉及更改其他类中使用的方法的方法签名,则还需要替换它们。只要不更改公共方法,受保护方法或默认方法的方法签名,您就可以了。

作为旁注,如果这是你经常做的事情,你会很快意识到为什么经常将对象传递给方法而不是单个参数。

public MyObject getObject(MyObject2 mySecondObject)

vs

public MyObject getObject(int a, int b, int c)

当您需要向传递给方法的对象添加新属性时,方法签名不会更改,但是当您在方法签名本身上添加或删除参数时,它会对所有依赖项创建连锁反应,要求你编译和替换那些类文件。

作为强调的最后一点,值得注意的是,您对私有方法或私有变量甚至方法的定义所做的更改对其他类文件没有影响或影响。唯一重要的是你坚持你的方法与其他类的契约,因为输入和输出总是采用并返回相同的数据类型。

这突出了封装实例变量的重要性以及这些依赖关系如何从其他类中隐藏。

答案 1 :(得分:2)

是的,你可以做到。此外,由于热点,类甚至会在运行时重新加载,因此您不必重新启动服务器。这在开发周期中非常有用。

但要小心更换一个单独的课程。如果类引用了您环境中更改的其他类,则替换将在服务器上失败。

答案 2 :(得分:1)

我假设您正在谈论'离线'替换(我的意思是您可以重新启动服务器)。

在这种情况下,以下解决方案可行: Java使用 classpath 变量。在那里,您可以定义一系列jar /文件夹,您的进程将在其中查找文件。

所以你可以做到以下几点:

  1. 创建新类(它应该具有相同的名称并位于同一个包中)并编译。
  2. 在服务器上创建您计划存储更新课程的文件夹。

  3. 更新 classpath 变量(可能在应用程序的启动脚本中),以便此文件夹在之前显示

  4. 重新启动服务器。现在,您的新课程将在旧课程之前解决并加载。

  5. 注意: 这适用于“独立”应用程序,通常适用于那些不使用自定义类加载器的应用程序(例如,应用程序服务器就是这种情况)。

    更复杂的解决方案可以基于定义您的类加载器,它将查看这样的文件夹(如我所述)并尝试从那里加载资源。

    希望这有帮助。