Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Developer
dkonigs
Posts: 256
Registered: ‎07-25-2008
My Device: Bold 9900

Targeting multiple BB OS versions from a single source tree?

Out there in the wild, we may have few v4.0 devices left, plenty of v4.1 devices, v4.2 is the most popular at this point, and of course v4.3 to v4.6 accessible to us in some capacity.  (my brand-new 8820 is only a v4.2, for example)

 

Now many of us want to support the latest and greatest features when we can, but don't want to leave many users in the dust in the process.  So I'm interested in having a single application source tree that I can build for say, v4.0, v4.1, and v4.2.  Right now I've done this for 4.0 and 4.1, using some wrapper classes and conditional compilation rules.  It feels quite hack'ish, and gets the job done.  But there has to be a better way.

 

Is anyone else out there trying to target multiple BB OS versions with their apps, and if so, how do you do it?

 

(FYI, my main build process now uses ant and bb-ant-tools)

New Developer
rosskevin
Posts: 9
Registered: ‎07-16-2008
My Device: Not Specified

Re: Targeting multiple BB OS versions from a single source tree?

We built a custom, extensive Maven2 plugin to generate builds from one source tree amongst other things.  I agree, pre-processor directives definitely make you feel dirty at the end of the day, and they very clearly turn your code into a mess of commented conditionals.

 

We have implemented some hand coded class weaving with javassist, but would love to be utilizing some AOP static class weaving if either we had time to make the necessary changes to one of the current AOP implementations or we had a financial investment to make it happen.  Unfortunately (or fortunately depending on how you look at it), we are too busy with customer work to spare any more cycles to work on something like this.

 

So, the quick and easy way to do this in a reasonably clean way is whole source file replacement during the build, though you then need to make sure that all your source files for the specific OS version are somewhat kept in sync.  The nasty way to do it is with pre-processor directives, but this is arguably the easiest for most developers to understand.

 

The elegant and most powerful way to do it is with AOP.  I guess you could say that our solution is somewhat between them all since we do some weaving of runtime classes at build time, but it could be so much better with AOP.  Anyone else want AOP in the RIM environment?

 

 

Kevin Ross | President | Metova
www.metova.com
Developer
richard_puckett
Posts: 191
Registered: ‎04-03-2008
My Device: Bold 9700

Re: Targeting multiple BB OS versions from a single source tree?

[ Edited ]

I ported AspectJ to BlackBerry about six months ago but haven't used it much due to some limitations (wanted to use it for performance logging, but it's not possible to retrieve things like method names during execution, so I dropped it).  IIRC it took literally less than a day to get it working on BlackBerry.

 

The way I handle compiling for different OSes is by coding to interfaces.  If I need a service that dependent on an OS I create an interface with defines a contract.  Then I provide an OS-specific implementation for each OS that I need to support.  The OS-specific implementation lives in its own high-level folder, each of which get pulled and compiled at build time based on which OS I'm targeting.

 

For example:

 

Folder src/common/com/mycom/foo:

package com.mycom.foo;

 

public interface ISomeService { public void doSomethingOSSpecific(); }

 

 

In each of

src/420/com/mycom/foo

src/421/com/mycom/foo

src/430/com/mycom/foo:

 

package com.mycom.foo; public class SomeServiceImpl { public void doSomethingOSSpecific() { // OS specific implementation of something } }

 

 

During development I need to manually put one of the OS-specific folders on my classpath and change which version of net_rim_api.jar I'm pointed at, but I'm looking at possibly making a plugin (Eclipse or NetBeans) which would have this kind of functionality so I could select my target OS from a dropdown and have the right things happen.

 

The build system simply needs to iterate over the list of supported OSes and build a cod for each, pulling in the appropriate source folder and net_rim_api.jar for each.  That means I have one cod generated for each OS (which may include siblings), but this is something I don't think we can get around if we're going to have OS-specific functionality thanks to the way things get linked.

 

Right now there's a little manual management involved but it works well and keeps code functionality cleanly separated.

Message Edited by richard_puckett on 07-26-2008 10:08 PM
Developer
dkonigs
Posts: 256
Registered: ‎07-25-2008
My Device: Bold 9900

Re: Targeting multiple BB OS versions from a single source tree?

My approach is somewhat similar to yours, though preventing IDEs from complaining about conflicts in that situation can be a pain.  I do it by just having a front-end that tries to load each implementation by-name on startup, succeeding only on the one that actually got built-in.  Of course your approach is better, if you've solved the whiny-IDE problem, or simply don't frequently show the implementations to the IDE.  Regardless, I'd be curious to see how you actually handle the implementation-loading portions.

 

However, this approach has one fundamental problem.  Its only practical for support/utility API calls.  The moment you're trying to use some OS-specific feature of a more common core class,  it feels like you're jumping through too many hoops.  I'm lucky at the moment, since the only feature-difference between 4.0 and 4.1 (that my app cares about) is the built-in Base64 encoding/decoding support.  Of course, with 4.1/4.2, that will change.

Developer
jiggak
Posts: 28
Registered: ‎07-24-2008
My Device: Not Specified

Re: Targeting multiple BB OS versions from a single source tree?

I've been using a tool I wrote to perform preprocessing during my ant build procedure.  The syntax is very C preprocessor like and properties defined in the build script are propagated through to preprocessor.

 

javapp

 

Preprocessing does seem like a bit of a hack and it can certainly be miss/over used to the point that the code base becomes not so nice to look at.  I have yet to come up with a more elegant solution to this problem.

 

Must say, Richards solution sounds interesting.

New Developer
alexb
Posts: 2
Registered: ‎07-31-2008
My Device: Not Specified

Re: Targeting multiple BB OS versions from a single source tree?

RIM once suggested to me that rather than using ant to compile multiple builds for each OS, dynamically load the specific class you need when the app starts up after checking the OS level.

 

Here's the quote:

"The other way is to use one main code base and use libraries that support the extended features of newer apis like trackball, SDCard, camera, etc.  You can then use Class.forName() to dynamically load the available libraries as needed."

 

Has anyone implemented something like this? 

 

Developer
dkonigs
Posts: 256
Registered: ‎07-25-2008
My Device: Bold 9900

Re: Targeting multiple BB OS versions from a single source tree?

Actually, that's exactly how I do it.  Well, I do use build rules so that I don't compile unnecessary code into my app (simply having said code in the .cod was causing 4.0 compatability issues for me once).  But I do name-based loading for my API interface wrappers.

 

The one thing I never figured out, however, was how I actually determine my running OS version from within my app.  Anyone else know?

Developer
richard_puckett
Posts: 191
Registered: ‎04-03-2008
My Device: Bold 9700

Re: Targeting multiple BB OS versions from a single source tree?

Let me just post how I create my User-Agent string, which also contains how I get the current OS.

 

public static String getOSVersion() { String swVersion = null; ApplicationManager appMan = ApplicationManager.getApplicationManager(); ApplicationDescriptor[] appDes = appMan.getVisibleApplications(); int size = appDes.length; for (int i = 0; i < size; i++){ if ((appDes[i].getModuleName()).equals("net_rim_bb_ribbon_app")) { swVersion = stripBuildId(appDes[i].getVersion()); break; } } return swVersion; } public static String getUserAgent() { String version = getOSVersion(); return "BlackBerry" + DeviceInfo.getDeviceName() + "/" + version + " " + "Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/" + Branding.getVendorId(); } private static String stripBuildId(String version) { int index = version.lastIndexOf('.'); return version.substring(0, index); }

 

Developer
dkonigs
Posts: 256
Registered: ‎07-25-2008
My Device: Bold 9900

Re: Targeting multiple BB OS versions from a single source tree?

Ok, so a bit kludgy, and it requires the signed APIs, but it works.  I've thus far been explicitly avoiding the signed APIs (my app is open-source and I don't want to impose such requirements on others who might want to build/run it), but I know I'm going to have to bite that bullet soon enough.  Just too many features I want to implement that really need those APIs.