views:

52

answers:

1

I want to be able to support multiple versions of Java ME without having to have multiple builds. I already know how to detect the profile/configuration/supported JSRs. My problem is that knowing whether the JSR is supported at run time doesn't allow me to use all the features as Java-ME does not provide support for reflection.

For if I call a function added in a later version anywhere in the code - even a location that will never be run, then this could cause an error during resolution on some JVMs. Is there any way round this?

+1  A: 

If you only need to access the class C through an interface which you know you will have access to, then it is simple enough:

Class myClass= Class.forName("C");
MyInterface provider = (MyInterface)(myClass.newInstance());
provider.interfaceMethod()

If an interface is insufficient, then we can use create S, a wrapper class for C, as documented here. S has a static block so that an exception is thrown during class resolution if C is unavailable.

static {
    try {
        Class.forName("C");
    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }
}

public static void checkAvailable() {}

We also have an empty method CheckAvailable that is called in a static block to force resolution to occur in a location where we can catch the exception if it fails and set a boolean with whether the class is available. We then ensure that we only use the methods in S when this boolean is true.

Alternatively, we can use the method here:

Basically, you create a new package P, with a public abstract class A and a concrete subclass S private to the package. A has a static method getS that returns an instance of S or null if an exception is thrown during instantiation. Each instance of S has an instance of C so it will fail to instantiate when C is unavailable - otherwise it will succeed. This method seems to be a bit safer as S (and hence all the C APIs) are package private.

Casebash