代码之家  ›  专栏  ›  技术社区  ›  Redwood

如何在编译/运行时有条件地删除应用程序的一部分?

  •  1
  • Redwood  · 技术社区  · 15 年前

    我有一个Java应用程序,它运行在一个嵌入式设备上。因为不同的设备运行不同版本的设备sdk,所以我必须针对~5种不同的设备sdk组合进行构建。

    其中一个组合不支持现有对象上的特定方法,并且完全从SDK中省略了另一个对象。

    我在程序中使用这个方法和对象,但只在特定的配置中使用,所以我只想回滚到不支持它的设备上的另一个配置。

    我很乐意在编译或运行时执行这种回退行为。

    有条件地删除此代码最简单的方法是什么?

    代码在其他方面是相同的,因此我不希望为两个SDK创建两个单独的代码分支。

    我使用一个Ant脚本构建我的应用程序。

    如果相关的话,我的应用程序必须基于相当旧的JDK版本(1.1.8/1.2)构建。

    2 回复  |  直到 15 年前
        1
  •  2
  •   Stephen C    15 年前

    @劳伦斯约翰斯顿的自答草图如何在构建时做到这一点。我认为这基本上是正确的想法,但您可能不希望插件API抛出检查过的异常。理想情况下,您希望旧平台的实现尽最大努力来执行请求的功能。

    如果您想在运行时做出决定,可以:

    • 将类的不同版本放入单独的JAR文件中,并使用包装脚本在应用程序类路径中包含适当的JAR。

    • 使用 Class.forName() 动态加载适合平台的类版本。

    无论哪种情况,您都需要确保基本应用程序类(用于所有平台)不会静态地依赖于任何更高级的sdk/jdk。

    最后,我倾向于摒弃Java的古老版本。许多年前,他们是“生命的终结”,支持他们的要求显然阻碍了你。例如,在核心应用程序中向后兼容性的要求意味着它不能利用最近Java发行版中添加的许多新特性。你的客户中有多少人还在使用那些古老的Java版本?为什么他们不能升级他们的平台?他们真的需要最新版本的应用程序吗?

        2
  •  2
  •   Redwood    15 年前

    一个想法是创建两个具有相同接口、完整实现和存根的类,这两个类都具有issupported()方法,并且存根中的所有其他方法都会引发一个unsupportedOperationException。然后我可以在编译期间在Ant脚本中有条件地包含正确的类。

    我选择使用这种方法而不是更动态的方法@stephen c,因为它非常适合我们的目的,而且我们对设备(包括设备文件系统)的访问非常有限,因此很难部署多个JAR、设置类路径等。

    我最后做的是:

    1. 将需要存根的类移动到单独的包中。
    2. 创建新目录 mypackagenamestub 并将要存根的文件复制到其中。确保您的IDE不会更改要存根化的文件的包声明。
    3. 我们已经在Ant脚本中设置了sdk path属性,该属性是基于应用程序所基于的sdk构建的,因此我添加了另一个属性 omit.unsupportedmode (意译)并在适当的情况下将其设置为真。
    4. 使用条件任务设置要传递到的排除属性的值 javac ,例如 **/MyPackageStub/** **/MyPackage/** 基于 省略不支持的模式 .