开发者

How do I conditionally remove a portion of my application at compile/run time?

开发者 https://www.devze.com 2023-01-24 11:26 出处:网络
I have a Java application which runs on an embedded device. Because different devices run different versions of the device SDKs I must build against ~5 different device SDK combinations.

I have a Java application which runs on an embedded device. Because different devices run different versions of the device SDKs I must build against ~5 different device SDK combinations.

One of these combinations does not support a specific method on an existing object and omits another object entirely from the SDK.

I use this method and object in my program, but only in a certain configuration, so I would like to just fallback to another configuration on devices which do not support it.

I would be happy to do this fallback behavior at compile or run time.

What's going to be the easiest way to conditionally remove this code?

The code is otherwise ide开发者_StackOverflow社区ntical so I would prefer not to create two separate branches of code for the two SDKs.

I build my application using an Ant script.

My application has to build against a rather old version of the JDK (1.1.8/1.2) if that's relevant.


@Lawrence Johnston's self-answer sketches how to do this at build time. I think this is basically the right idea, but you probably don't want the plugin API throwing checked exceptions. Ideally, you want implementations for the older platform to make a "best effort" attempt to perform the requested function.

If you want to make the decision at runtime you could:

  • put the different versions of the class into separate JAR files and use a wrapper script to include the appropriate JARs in the application classpath.

  • use Class.forName() to dynamically load the version of the class that is appropriate to the platform.

In either case, you need to make sure that the base application classes (that are intended to work on all platforms) do not statically depend on any of the more advanced SDKs/JDKs.

Finally, I'd be inclined to desupport ancient versions of Java. They were "end-of-lifed" many years ago, and the requirement to support them is clearly holding you back. For instance, the requirement for backwards compatibility in your core application means that it cannot make use of the many new features added in recent Java releases. How many of your customers are still using those ancient Java releases? Why can't they upgrade their platform? Do they really need the latest version of your application?


One idea is to create two classes with the same interface, a full implementation and a stub, both with an isSupported() method and having all other methods in the stub throw an UnsupportedOperationException. Then I could conditionally include the correct class during compilation in my Ant script.

I elected to go with this rather than the more dynamic approach @Stephen C because it works perfectly well for our purposes and our access to the device (including the device filesystem) is quite limited, making it difficult to deploy multiple jars, set classpaths, etc.

What I ended up doing was as follows:

  1. Move the classes which require stubbing into a separate package.
  2. Create a new directory mypackagenamestub and copy the files to be stubbed into it. Make sure that your IDE does not change the package declarations for the files to be stubbed.
  3. We already set the SDK path property in our Ant script based on which SDK the application was being built against, so I added another property omit.unsupportedmode (paraphrased) and set it to true where appropriate.
  4. Use a condition task to set up a value to pass to the excludes attribute of javac, e.g. **/MyPackageStub/** or **/MyPackage/** based on omit.unsupportedmode.
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号