有没有一种方法在Java中将一个类“别名”为另一个类?

14
我有以下API兼容性问题,并正在寻找解决方法。
TL;DR:在Java中是否有创建类的“别名”的方法? 例如,有没有一些技巧可以使com.acme.foo.SomeEnum成为com.acme.bar.SomeEnum的别名?
长话短说,我正在使用一个功能强大的Java工具,该工具还支持插件。 没有严格定义的公共API(你可以接触和不能接触的),只有私有/受保护/包/公共类、方法和字段。 有定义好的扩展点(例如,扩展com.acme.plugin.Plugin类),但是然后您将可以访问该工具内部的广泛区域。
在最近的小版本更新中(例如,1.2.31.2.4),工具开发人员已将一个枚举类移动到另一个包中-com.acme.foo.SomeEnum变为com.acme.bar.SomeEnum。 我认为它被认为只是一个微不足道的重构,而不是严重的重组。
然而,这个类似乎已被许多插件使用。 结果是这些插件现在与最新版本不兼容。 大部分插件非常有用,但并没有积极维护。 人们几年前编写了它们 - 它们在多年的版本更新中工作正常。 因此,这可能对该工具的插件生态系统产生负面影响。
我的问题是,如果有一种方法可以在Java中创建com.acme.foo.SomeEnum的“别名”来适应com.acme.bar.SomeEnum吗? 这将允许旧插件继续与新版本的工具一起使用。
某些类装入器技巧? 在JavaScript中,这将很容易进行Shim操作,但在Java中呢?

为什么我要问这个问题。我是该插件的作者,它包装了所讨论的工具。因此,我可以轻松地为这个咖啡加入我的糖,例如类加载器等。如果有一种技术方法可以使这项工作,那么至少对于Maven用户来说,我将能够保存大多数工具的插件生态系统。

我已经就此联系了该工具的供应商,但不确定是否成功。

请明确一点 - 我不是所讨论工具的供应商。我(a)为该工具编写插件(并没有大问题更新我的插件),(b)是“the-tool-maven-plugin”的作者,该插件允许在Maven构建中执行该工具。我在该工具上也经常进行咨询,并关心其生态系统(有很多非常有用的插件)。


更新

故事结束:该工具的开发人员考虑到了我的观点,并决定撤销更改。为此点赞!


1
简而言之,没有。 - Hot Licks
2
愚蠢的想法:你能在你的代码中定义一个 com.acme.foo 包,创建 SomeEnum 并查看其余生态系统是否继续工作吗?我从未测试过这样的事情,不知道是否可行。 - Laf
1
有一个鲜为人知的 Proxy 类可以满足你的需求。Kabutz教授已经多次介绍过它们,包括 第五期第181期 - OldCurmudgeon
@OldCurmudgeon 嗯,这个静态代理看起来非常有前途。为什么不把它发布为一个答案呢? - lexicore
1
这就是为什么在第一次发布之前确保强大的API设计非常重要。最好的选择是重新打包,正如@EJK所提到的那样。虽然这不太美观,但你正在做的事情受到了反对,所以我建议选择两个中更亮的那个(除非你不介意保留原始版本而不进行重构)。 - Dioxin
显示剩余14条评论
1个回答

4
我建议使用jarjar。这是一个工具,可以让您重新打包库中的类。您可以针对最新版本的工具运行此工具,并将SomeEnum类移动到不与插件冲突的软件包中。 入门指南文档有一个例子,使用jaxen.jar,看起来与您的情况相关。

你的意思是重新包装那个工具吗?这是一个非常有趣的想法。 - lexicore
1
一个非常好的想法。这会部分地起作用。缺点是针对 版本的插件将会失败。只能支持一种版本,而不是同时支持旧版本和新版本。如果可以的话,一个别名可能会允许两个版本并行运行。 - lexicore
但是失败只会发生在明确引用SomeEnum类的新库和插件中,对此我表示同意,但这并不是一个完美的解决方案。 - EJK
是的,如果他们这样做。而且他们会这样做。那个类对于某些任务来说非常重要。 - lexicore
1
@lexicore - 你是否考虑过直接编写旧版本的枚举(在其旧包中),编译它,并将生成的类文件注入到工具的jar中?这样,你就可以在工具中拥有枚举的两个版本。这是一个非常鹰派的短期解决方案,但似乎可以适用于针对所有工具版本编译的插件。 - EJK
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接