I have different projects in Eclipse (java me midlets) which all need to share code. Currently I duplicate things, but this is not ideal.
What is the best way to do this?
Thanks!
EDIT:
I tried to add another project in the Build Path, but then, when running the Midlet in a Emulator, I get the following ERROR:
Uncaught exception java/lang/NoClassDefFoundError: clientlibrary/ov9292/Ov9292Client.
You can create a Java Project which will contain the shared code and have other projects reference it. When deploying you can pack this project as a separate jar file.
Have you considered creating a shared library instead of just shared code? Export to a JAR file and import that into the dependent products.
The up-side of doing this (vs just referencing the shared code) is that it will force you into more rigorous practices. You will now have an API that must be maintained and versioned cleanly. It will also make you better consider what's shared and what's not. This will likely lead to better encapsulation, and hopefully better testing.
I'm not saying you lack these things now. Just that creating a common-foo.jar can often encourage better habits.
Related
I have written a common class which I want to use in separate Blackberry applications. This class is not in a separate project but just at a common location and I have linked the path of the common class in Java Build Path. I have added same common path to both of my BB applications and they builds and installs without any problem. When I run one application, it start running but when I run the other application, it gives error message "class xxx multiply defined" error and exits.
Any idea what is going wrong here. Thanks in advance
Regards,
Braj
BlackBerry doesn't work as other Java platforms. In BB Java, you can't have two classes with the same full qualified name, even if they live in different projects.
You'll have to rename one of them (either change the class name or the package name) for it to work.
In fact, the only platform where I have seen this restriction is BB. It is a real pain in the ass since you can't reuse a jar library in different projects without renaming it.
UPDATE:
This is the official article on the topic:
http://supportforums.blackberry.com/t5/Java-Development/Application-throws-quot-multiply-defined-quot-error-at-start-up/ta-p/501498
All applications in RIM OS run under one instance of Java Virtual Machine. And therefore it is allowed only one class with particular full qualified name. Adding another class with the same name will lead to failure upon running both of these classes.
There is a library thing, supported in RIM OS, but I do not recommend to use libraries in your project, unless it is very necessary.
It is because if you have several apps with the same library, but with different versions of libraries you may get the same error you reported in your question. And it is hard to manage libraries when you have many applications which use these libraries.
I recommend to copy source code of your library to the project you are working on. Copy via refactoring, to change all full qualified names of classes included in that library.
Thanks guys for replying. I have created a common library and put common code in that. Now I can use this library in different applications without any problem.
However, when I install my applications using BB desktop Manager, the library appears as part of first application but not in second application. I assume it is because, second application realizes that the library is already been included so doesn't need to include it again.
I recently started using Eclipse IDE and have read at a number of places that one shouldn't use the default(src) package and create new packages.
I just wanted to know the reason behind this.
Using the default package may create namespace collisions. Imagine you're creating a library which contains a MyClass class. Someone uses your library in his project and also has a MyClass class in his default package. What should the compiler do? Package in Java is actually a namespace which fully identifies your project. So it's important to not use the default package in the real world projects.
Originally, it was intended as a means to ensure there were no clashes between different pieces of Java code.
Because Java was meant to be run anywhere, and over the net (meaning it might pick up bits from Sun, IBM or even Joe Bloggs and the Dodgy Software Company Pty Ltd), the fact that I owned paxdiablo.com (I don't actually but let's pretend I do for the sake of this answer) meant that it would be safe to call all my code com.paxdiablo.blah.blah.blah and that wouldn't interfere with anyone else, unless they were mentally deficient in some way and used my namespace :-)
From chapter 7, "Packages", of the Java Language Spec:
Programs are organized as sets of packages. Each package has its own set of names for types, which helps to prevent name conflicts.
I actually usually start by using the default package and only move it into a real package (something fairly easy to do with the Eclipse IDE) if it survives long enough to be released to the wild.
Java uses the package as a way to differentiate between classes. By using packages, you can have an org.example.Something class and an org.example.extended.Something class and be able to differentiate between them even though they are both named Something. Since their packages are different, you can use them both in the same project.
By declaring a package you define your own namespace (for classes). This way if you have two identical classes using a different package name (namespace) will differentiate between which one you want to use.
The main reasons I can think of are:
It keeps things organised, which will help you (and others!) know where to look for classes/functionality.
You can define classes with the same name if they are in different packages.
Classes/etc in the default package cannot be imported into named packages. This means that in order to use your classes, other people will have to put all their classes in the default package too. This exacerbates the problems which reasons 1 & 2 solve.
From a java point of view, there are two general dev/deploy lifecycles you can folllow, either using ant to build and deploy, or the maven lifecycle. Both of these lifecycles look for source code and resources in local directories, and in the case of maven, in defined repositories, either locally or on the net.
The point is, when you set up a project, for development and eventually deployment, you want to build a project structure that is portable, and not dependent on the IDE, ie. your project can be built and deployed using either of your build environments. If you use a heavy dependence on the Eclipse framework for providing class variables, compile paths, etc.. you may run into the problem that your project will only build and deploy using that configurationj, and it may not be portable to another developers environment, so to speak.
I'm having trouble getting a shared library working in a Java EE environment.
In particular, the library contains some helpers for common JMS activities. However, as soon as the code enters a library function that requires anything from javax.jms it's triggering a ClassNotFound exception (claiming it can't find javax.jms.Message, for instance.)
How do I get around this? I'm placing the shared lib under $AS_HOME\lib\endorsed -- does it belong elsewhere? I have tried also packaging all the dependencies inside the jar; this doesn't seem to make much of a difference.
I am really hoping this is much more straightforward than it is seeming right now. In order just to get it working, I've refactored the helper into a helper-per-module within each component that requires the functionality. Note that this is working, so I'm thinking the issue at this point is just classpath problems? Thanks for any advice!
The best practice is to put the jms.jar in:
$AS_HOME/domains/<your domain>/lib
but you could always just place them in:
$AS_HOME/lib/
If you are not familiar with domains, take a quick glance at Concept of a GlassFish Domain
When writing code in an Eclipse project, I'm usually quite messy and undisciplined in how I create and organize my classes, at least in the early hacky and experimental stages. In particular, I create more than one class with a main method for testing different ideas that share most of the same classes.
If I come up with something like a useful app, I can export it to a runnable jar so I can share it with friends. But this simply packs up the whole project, which can become several megabytes big if I'm relying on large library such as httpclient.
Also, if I decide to refactor my lump of code into several projects once I work out what works, and I can't remember which source files are used in a particular run configuration, all I can do it copy the main class to a new project and then keep copying missing types till the new project compiles.
Is there a way in Eclipse to determine which classes are actually used in a particular run configuration?
EDIT: Here's an example. Say I'm experimenting with web scraping, and so far I've tried to scrape the search-result pages of both youtube.com and wrzuta.pl. I have a bunch of classes that implement scraping in general, a few that are specific to each of youtube and wrzuta. On top of this I have a basic gui common to both scrapers, but a few wrzuta- and youtube-specific buttons and options.
The WrzutaGuiMain and YoutubeGuiMain classes each contain a main method to configure and show the gui for each respective website. Can Eclipse look at each of these to determine which types are referenced?
Take a look at ProGuard, it is a "java shrinker, optimizer, obfuscator, and preverifier". I think you'll mainly be interested in the first capability for this problem.
Yes it's not technically part of Eclipse, as you requested, but it can be run from an Ant script, which can be pretty easily run in Eclipse.
I create more than one class with a main method for testing different ideas that share most of the same classes.
It's better to be pedantic than lazy, it saves you time when coding :-)
You can have one class with a main method that accepts a command-line argument and calls a certain branch of functionality based on its value.
I have recently joined a project that is using multiple different projects. A lot of these projects are depending on each other, using JAR files of the other project included in a library, so anytime you change one project, you have to then know which other projest use it and update them too. I would like to make this much easier, and was thinking about merging all this java code into one project in seperate packages. Is it possible to do this and then deploy only some of the packages in a jar. I would like to not deploy only part of it but have been sassked if this is possible.
Is there a better way to handle this?
Approach 1: Using Hudson
If you use a continuous integration server like Hudson, then you can configure upstream/downstream projects (see Terminology).
A project can have one or several downstream projcets. The downstream projects are added to the build queue if the current project is built successfully. It is possible to setup that it should add the downstream project to the call queue even if the current project is unstable (default is off).
What this means is, if someone checks in some code into one project, at least you would get early warning if it broke other builds.
Approach 2: Using Maven
If the projects are not too complex, then perhaps you could create a main project, and make these sub-projects child modules of this project. However, mangling a project into a form that Maven likes can be quite tricky.
If you use Eclipse (or any decent IDE) you can just make one project depend on another, and supply that configuration aspect in your SVN, and assume checkouts in your build scripts.
Note that if one project depends on a certain version of another project, the Jar file is a far simpler way to manage this. A major refactoring could immediately means lots of work in all the other projects to fix things, whereas you could just drop the new jar in to each project as required and do the migration work then.
I guess it probably all depends on the specific project, but I think I would keep all the projects separate. This help keep the whole system loosely coupled. You can use a tool such as maven to help manage all the dependencies between the projects. Managing dependencies like this is one of maven's main strengths.
Using Ant as your build tool, you can package your project any way that you want. However, leaving parts of your code out of the distribution seems like it would be error prone; you might accidentally leave out necessary classes (presumably, all of your classes are necessary).
In relation to keeping your code in different projects, I have a loose guideline. Keep the code that changes together in the same project and package it in its own jar file. This works best when some of your code can be broken out into utility libraries that change less frequently than your main application.
For example, you might have an application where you've generated web service client classes from a web service WSDL (using something like the Axis library). The web service interface will likely change infrequently, so you don't want to have the regeneration step reoccurring all the time in your main application build. Create a separate project for this piece so that you only have to recreate the web service client classes when the WSDL changes. Create a separate jar and use it in your main application. This style also allows other projects to reuse these utility modules.
When following this style, you should place a version number in the jar manifest so that you can keep track of which applications are using which versions of your module. Depending on how far you want to take this, you could also keep a text file in the jar that details the changes that have occurred for each revision (much like an open source library).
It's all possible (we had the same situation some years ago). How hard or easy it'll be depends on your IDE (refactoring, merging, organizing new project) and you build tool (deploying). We used IDEA as IDE and Ant as build tool and it wasn't too hard. One sunday (nobody working+committing), 2 people on one computer.
I'm not sure what you mean by
"deploy only some of the packages in a jar"
I think you will need all of them at runtime, won't you? As I understood they depend on each other.