我们正在为嵌入式JavaME设备提供软件。除了标准的JavaME API之外,该设备还提供了一些专有的API,例如com.somecompany.icm.io
这样的包。
由于存在法律问题,我们会在以后的com.othercompany.io
固件版本中重命名这些软件包,例如但具有相同的类名,接口和功能。
现在,我能做的就是在我们的代码库上运行sed
或类似代码,并重命名每个必需的包,然后将其提交给我们的VCS,作为"新的"版。不幸的是,我们需要为两个固件版本提供更新,因此需要将错误修复甚至功能合并回旧版本。
我正在考虑有一个特殊的ANT构建任务,首先将所有源复制到另一个目录,运行sed
脚本然后再次编译它。这不是很优雅但可能有用(还没有做到这一点)。
我知道这可能是一个非常特殊的情况,但也许有人可以提出更智能的解决方案。
[UPDATE]
我已经考虑了一段时间并提出了以下想法:我写了一个小应用程序,其中包含以下行:
try {
System.out.println("[somecompany] File 'foo' exists: " + com.somecompany.icm.io.File.exists("foo"));
} catch(NoClassDefFoundError ex) {
System.out.println("[othercompany] File 'foo' exists: " + com.othercompany.io.File.exists("foo"));
}
我编译了这个,将somecompany和othercompany的库都提供为classpath。 File.exists
只是测试这个想法的一些任意静态方法。
它实际上适用于两个目标设备:
旧固件:
[somecompany] File 'foo' exists: false
新固件:
[othercompany] File 'foo' exists: false
但是,这仅适用于静态方法和类初始化。但是,这不会对类实例和实例方法访问起作用。
现在,可以做的一件事是为每个固件版本编写两个版本的工厂类。然后,我可以使用上面的代码在运行时确定正在运行哪个固件并加载正确的工厂类。
MyFactory factory;
try {
com.somecompany.icm.io.File.exists("foo");
factory = new SomeCompanyFactory();
} catch(NoClassDefFoundError ex) {
factory = new OtherCompanyFactory();
}
// use the factory to create instances of classes of the right package
显然,实例必须包含在实现公共接口的类中,这在我的情况下是适用的。
这会导致一些类开销(就类的数量和jar文件大小而言)但是由于这些类不会被加载,因此对内存使用量应该没有影响(或者只是一点点) (我们的目标RAM非常有限)。