views:

134

answers:

2

What I'm trying to do

I'm coding a J2ME midlet, and I want to use JSR-75 to write files. I also want to be able to run my app on device that don't have support for JSR-75.

How I'm doing it

I found a website that explains how to do this (forgot the URL, sorry):

  • Create a public abstract class ("Service") that exposes all functionality.
  • Create a package-private class ("ServiceImplementation") extending this abstract class, implementing all functionality.
  • Put both in a separate package, rendering Service the facade for the package.

To instantiate this class, the following method from the abstract class is used:

public static Service getInstance() {
    try {
        Class.forName("javax.microedition.io.file.FileConnection");
        Class c = Class.forName("my.package.Service");
        Service service = (Service) (c.newInstance());
        return service;
    } catch (Exception e) {
        return null;
    }
}

What goes wrong

This works perfectly when JSR-75 is present. The problem is that I want this midlet to run on non JSR-75 devices as well, and this code throws a ClassNotFoundException: javax/microedition/io/file/FileConnection when I try do do so, even though I'm catching all Exceptions.

I've done a project-wide search to ensure that I'm not using FileConnection anywhere else but in Service and ServiceImplementation.

Does anyone know how I'm supposed to do this?

A: 

Apparently I can use this:

System.getProperty("microedition.io.file.FileConnection.version");

If that returns null, JSR-75 isn't supported. If it returns anything else, it is.

Both approaches should work.If you replace try { Class.forName("javax.microedition.io.file.FileConnection"); ... etc in the above code with if (System.getProperty("microedition.io.file.FileConnection.version") != null) { ... does everything work OK?
funkybro
Yeah, this approach works. I wanted to accept my answer as the accepted answer, but I have to wait 5 more hours...
A: 

Slightly confused about what you're doing, especially with two classes in different packages both called Service! But I have encountered this problem when writing code to run on handsets both with and without certain JSRs.

Are you referencing JSR-75 classes in your Service class? I suspect that even though you're not instantiating the Service class, it's still being loaded. The JVM is then coming across these classes which are not present.

Move all references to JSR-75 classes into a class which is referenced from the Service class.

funkybro
I'm already doing that. I only have one class named Service, and one named ServiceImplementation, both in the same package. The latter is package-private, and that's the only class where I reference JSR-75 classes. Either way, it's solved now. I just don't understand why an exception that should've been caught was still thrown throug, causing the application to halt.
Is Service (accessed from all handsets) referencing ServiceImplementation (which references JSR-75)? Try moving the JSR-75 references to another class, referenced only from ServiceImplementation.
funkybro
Nothing references ServiceImplementation directly. The only "reference" is in Service, as follows: Class.forName("my.package.ServiceImplementation").newInstance(). But as you can see in the comments on my own answer, it works now.