02-20-2010 01:58 PM - edited 02-20-2010 02:00 PM
I would like to know if i can compile, seperately COD files and be able to access the seperated ones class and meathods. I am creating a program (almost done) that i would like to be able to ADD COD files in the future and be able to access the classes in them as if they where compiled together. Think of it as add-ons? Can this be done, and if so how? I took a quick look at Class, but thats more for streaming material. Software is 4.5 and its currently tested on the Curve 8330.
Solved! Go to Solution.
02-21-2010 12:57 AM - edited 02-21-2010 10:20 AM
Im sorry, should have mentioned i already did a search. I found and read about many issues with loading, updating libraries. but nothing to explain, even in a basic outline of what needs to be done with linking a DYNAMIC library class at runtime. all i need are the basic steps, like:
1) Create a new workspace, project and change it to library (this i understand)
2) create your class(s) as if you where creating an app(not sure if this is correct)
4) Create a new workspace, project
5) to access the class(s) in the library created earlier u need to(?)
Please note, that the library cod file name will not be known until runtime, and i would like to know IF the library can be stored on sdcard or if it has to be loaded as an app.
02-21-2010 12:31 PM
There are a number of issues that need to looked at here.
1) You can not run an application, or a library or any cod from the SDCard. You can load a cod from the SDCard (i.e. read it in, then create a module from it), but you need to have an appplication running to do this. See the CodeModuleManager class for details on how to create the module - reading it from SD Card is just File Connection API.
2) In J2ME land, all modules are preverified, which I think loosely means that all the modules know how they are going to interact with all the other modules and objects. This means you can't create an unknown Object in the middle of your application, nor can you call a method on an object that wasn't known at compile time. And you can reflect on an object to find out what methods are available. So while using a Library is useful, using it directly implies that you know what methods and what objects you are going to use, at compile time.
I suspect this makes what you are trying to do difficult.
All is not doom and gloom though. There are at least three options that might help.
a) If you have an application that uses a Library, it is possible to swap out the old Library cod and put a new one in its place, as long as the Object/method signatures that the application used in the old library are still present in the new library. So for example, it is possible to create OS specific Libraries that provide additional functionality. For example the Library might provide a Screen which in 4.6 and later that uses Borders, but the 4.5 version of the Library, the Screen does not.
b) You can create instances, using the default constructor, of classes in a cod that you know nothing about except the name of the class in that cod. You can do this using the class.forName. So you can tell if an optional cod is present and create Objects in that cod. However you are going to struggle to interact with these Objects, - you only have the Object methods!
c) It is possible to create an Interface that lets you get access to 'unknown' objects. I'm going to struggle to explain this. But let us say in the Application we have a Library cod that this application depends on, and in the Library we have an Interface. The Optional cod also has this same Library and so it can create Objects that obey this interface. Then, when you create the Object as I described in (b), you can can then see if this Object implements the Interface, and assuming it does, then you can cast it to that and now you can interact with it.
There are other options too, but I am really struggling to explain them in a few words with no pictures. I don't think I've explained the above very well as it is!
The summary is, that what you are trying to do is not going to be easy and you will need to think about how you implement it.
I hope this helps.
02-22-2010 12:44 AM
Thank you peter, you shed some light onto my situation. Some of these concepts i have read, but with no examples i didnt know where i could go. you explained it a little more clearly for me. Your Solution (c) is the one im looking for in this situation (Yes there is another one MORE complex, maybe not even doable). Lets say (as an example) My program is going to choose what module it wants to load at runtime, (from a selection, of lets say 3). The interface will be the same for these modules, but what they do is completely different. Translating a language would be an example. I want to translate from English to french, i want to load the French module (The name of the module is known at runtime, chosen by a pulldown). Using your solution (c), is this doable?
The more complex situation, is a little ways away. but i would like to try and find a way to Load/link a module, get a list of methods and be able to call those methods. (not knowing the methods until its loaded by reflecting on it.) The issue with Blackberry's reflection, is it has none that i can find. You can use Class and forName, but you cant use Method or getDeclaredMethods(). Did i miss something?
02-22-2010 04:39 AM
We do something similar to what you want to do, so let me explain how that works.
We have a Library cod that provides a Service Manager function. In that Library we have a ServiceInterface and a ServiceRegister. The idea is that Services can register themselves, then applications can ask the Service Manager if a Service is provided. The application knows the name of the Service it wants to use, it just asks the Service Manager if any object has registered themselves as a Service Provider for that name. If something has, the Service Manager can provide a ServiceInterface Object that the Application can use.
So in our implementation, each of the translation cods would register themselves, with a different name. The application would have to know the name of all the translation cods that it might use and ask the Service provider if such a Service is provided. It can then populate the pull down with the ones that it found.
Clearly this is not what you would like, (you don't want the application knowing the Service Name for each of the possible translations), so you would need to extend this processing so that the Service Manager can register multiple Service providers with the same Service Name, and supply this to the Application. But the basic principle is the same.
This relies on the Service Provider cod actually registering itself with the Service Manager. The Service Manager does NOT look for cods. Fortunately it is easy for a Service Provider Library to run some code at start-up to register itself. In any Library cod, libMain will be called, just like main is called in an Application cod, if the project has been registered to run at startup.
So this Service Manager mechanism does not use class.forName at all.
We have another Application which does use class.forName. But here the class knows the name of the cods that it might want to load, and just finds out which ones are present. Then it casts the Object supplied, to the Interface it expects and can use the Objects it finds. Works OK, but I think the Service Manager interface described previously is a better fit for what you want.
Moving on to your more complex situation. as noted in my previous post, reflection is not supported, so I don't think what you want to achieve here is possible. So, you didn't miss anything.