Search code examples
java-memultiple-versions

Supporting multiple versions without separate builds in JavaME


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?

Related Questions


Solution

  • 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:

    MyInterface provider=null;
    try{
        Class myClass= Class.forName("sysPackage.C");
        provider = (MyInterface)(myClass.newInstance());  
    }catch(Exception ex){
    }
    if(provide!=null){
        //Use provider
    }
    

    If C does not have an interface that can be used, then we can instead create a wrapper class S that will be a member of the interface instead.

    class S implements MyInterface{
        static {
            try {
                Class.forName("sysPackage.C");
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        } 
        public static void forceExceptionIfUnavailable() {}
        //TODO: Methods that use C. Class C will only be used within this class
    }   
    

    S has a static block so that an exception is thrown during class resolution if C is unavailable. Immediately after loading the class, we call forceExceptionIfUnavailable to make sure that the static block is run immediately. If it doesn't crash, then we can use the methods in S to indirectly use class C.

    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.