I am a C# developer and I am messing around with Java. In C# I would normally have my front end project and then when I need to add another layer to the project (i.e service layer etc) I would add a class library in the solution and add a reference to it.
What is the convention in Java? Do you add another Java project to the workspace and then reference the project? Or do you add a package to the project which contains your front end?
UPDATE
Sorry, I am using eclipse...hence the reference to 'workspace'
There's no real convention. When you say "workspace" you're not referring to Java, but rather a development environment (sounds like Eclipse). There are a number of ways to do it; you could do it the way you're suggesting, you could include the dependency via Maven, you could combine them all together in one project, etc.
Which to choose depends on your needs, who else will be consuming either the individual libraries or the completed project, and so on.
How to divide your source code depends a lot on the structure of your project. It is important to pay attention to a good code organization. You should keep classes for a common task or for a distinct application layer in own packages. You should watch for inter-package dependencies.
Using different "projects" (be it Maven or Eclipse projects) helps ensuring that you (your developers) do not violate structural boundaries because the compiler checks the dependencies (one project references the other project, like in C#/VS). Maven generates a build artifact (e.g. a JAR file) for every project.
To summarize, I think it is a good idea to create new individual projects for each program module in order to be able to manage the dependencies between the projects explicitly.
You are assuming everyone works with eclipse, it seems (your references to "workspace").
You can do anything you want, but keep in mind others might not be able to include 'separate' projects for various components of the application.
You can easily address that issue by using some build tool (ant, maven) to build appropriate jars for the various app components, like data-model, persistence, API, etc.
If you front-end is an RIA, might make more sense to develop it as a separate project, although not necessary. If your app is some sort of Java driven UI, you can still do whatever you want, in both cases make sure the UI components have their own package hierarchy.
Yes, I guess I would create a separate package. So your UI code might be in com.mycompany.app.ui, your service code in com.mycompany.app.service, etc. However you want to organize your classes is up to you. Java itself doesn't care what packages the classes are in. The packages just help to make the code more manageable for the developers.
Unlike most things in Java, there's no real convention defined for how to split up project.
In my experience, it makes sense to include code that serves a particular business purpose in a single project, and to separate out code that you intend to share between multiple projects, or code that is not specific to a particular business purpose (e.g. database access, JMS libraries, etc.), into a separate project.
If the UI and the server layer are being developed in a single project, which means packaged and deployed in the same WAR file, I'd create a new package for the service and add classes and interfaces as needed.
If the service layer is deployed separately, I'd add dependencies as a JAR to the web project. All I should need are clients for the service.
If you're working in Eclipse follow these steps:
1) Right-click the project and choose "Build Path"-"Configure Build Path..."
2) Switch to Libraries tab and click Add External JARs (or just Add JARs if they're already in the workspace).
3) Now you can either manually add import of the corresponding class, or just hit Ctrl+Shift+O (Source-Organize Imports) and Eclipse will do the job for you.
I suggest you can use netbeans then you can create a java class library,when you deploy your project,netbeans will generate jar files for you,and place them at the right location.I'm also a ms developer,hope it helps
Related
Recently I started to use Maven for managing my project's structure more efficiently. However, since i'm at the same time learning JAVA, i've come to a dead-end, What is the difference between a module in MAVEN and a JAVA package ?
Since packages are used to group classes/interfaces that share common purpose:
(source: docs.oracle)
Definition A package is a grouping of related types providing access protection and name space management.
And i couldn't find a clear definition of a module, better stated than the vague:
(source: http://docs.jboss.org/tools/latest/en/maven_reference/html/creating_a_maven_application.html)
A Maven module is a sub-project
From what i read, we should create modules in order to separate logic in the project, business, domains, basically anything considered a s a separate entity.
Hence, why can't we do the same with usage of packages? Isn't the purpose the same?
I'm also negelecting all build-configurations here. If it's the only difference, then please provide argumentation when which one should be used.
Maven is a bundling tool, it assembles reusable parts of software together to an application, no matter if it is Java code, image resources or HTML templates. It builds your application so it can be run or deployed in a certain environment (local, testing, production etc.) All of this has nothing to do with Java packages.
You should care about Maven Modules if you (or others) want to reuse code that you have written. For instance, you wrote a web application that converts currencies and now you'd like to use the conversion logic (but not the web frontend) in another application. In that case you'd create one module for the web frontend and one module for the business logic.
A package is a collection of classes. A module is a collection of packages with build configuration.
If it was your own project you can organize them however you want with packages and/or modules. If you want to create a re-usable component (e.g. library) for multiple project you should use a module.
If you only have packages a project would have to include all of the packages (i.e. source files) directly for every library that it needed. Instead with module (remeber it also has build configuration) you can take the compiled output (e.g. .jar, .aar, etc) and include that in your project.
I have several projects that need the same core database and utility classes so I have decided to make a "core" module to put these in. Is there any way to use this module in multiple projects or am I using modules for the wrong purpose?
Yeah! While I obviously can't provide a thorough critique of how you're using modules given what you've told us, the fact that you've encapsulated reusable functionality in this one is certainly a good sign!
Given that such is the purpose of modules, surely intelliJ would want to make it easy to share them across projects - and they did: In the File menu, there's an option to "Import Module". Click that and walk through the wizard, selecting the directory where your module is stored, and it'll appear in your Projects menu as normal.
I have a server application and two Swing-based client applications. We're developing them in eclipse and there's a separate project for each.
Many classes are shared. For example, the my.server package has some classes for both the server and the clients while others are for the server only. Although I prefer to put them in the same package because they are closely related and some of them rely on package visibility, I don't want to distribute classes that an application does not need as not only would it bloat the file size, but also it would be a security risk.
At the moment, each of the server and the clients has the same jars, which is a mess. Ideally, I'd like to automatically create jars based on dependency as following.
Server:
server.jar: classes used by Server only
server-client1-common.jar: classes shared by Server and Client 1
server-client2-common.jar: classes shared by Server and Client 2
Client 1:
client1.jar: classes used by Client 1 only
server-client1-common.jar: classes shared by Server and Client 1
client-common.jar: classes shared by Client 1 and Client 2, but not Server
Client 2:
client2.jar: classes used by Client 2 only
server-client2-common.jar: classes shared by Server and Client 2
client-common.jar: classes shared by Client 1 and Client 2, but not Server
I realize that you can do this manually using ant, but it would be a maintenance disaster. Is there a tool that takes care of such dependency automatically?
What do you mean by "maintenance disaster"? If you create an ANT script, just run it and it will compile and pack the jars for you.
As a more robust alternative, you might use maven. For something more lightweight, the built-in eclipse export tool might work.
I cannot present you with a ready-to-go solution. Here's an idea though: create an annotation or a set of annotations like this:
#jarselector(types='server')
class ServerOnly {
...
}
#jarselector(types='server,client1')
class ServerAndClient {
...
}
Then create your own ant task by extending the jar task (or maven plugin) or write your own task, that takes this annotation and packages classes according to the annotation, which you would then be using as a filter.
You would only have to create the task once - I've done it in the past, it is less complicated than it sounds and the problem sounds big enough to warrant the effort.
Afterwards you have to annotate all your classes once (or depending on your implementation only those classes the clients need, or only those that are not shared by every jar etc.). Whoever sees a class can see immediately what it is used for. When creating a new class you can easily add the annotation.
I really don't think there is a ready made ant task or maven plugin that does this.
Alternatively - if you really cannot change your package structure - you could also use multiple source directories to keep the packages but split the files in different directories. Eclipse doesn't care how many source directories you use. You would then need to adapt your build tool just once for the source directories and could then sort the files that way.
One of the best practices regarding building applications is to have one jar per project.
Maven, for example, uses this as default. You can trick it to do otherwise, but it is better to join them instead of "fight" them.
http://maven.apache.org/guides/mini/guide-using-one-source-directory.html
http://www.sonatype.com/people/2010/01/how-to-create-two-jars-from-one-project-and-why-you-shouldnt/
So, in your case you should create 6 projects:
Server, Client1, Client2, ServerClient1Common, ServerClient2Common, ClientCommon
In order to select the classes needed, I don't think there is a tool, and probably you should know better what is the common functionality.
Create the Common projects, and add them to the build path - dependencies. Then start moving your classes into the Common project, leaving them in the same package.
For example, create ServerClient1Common project.
For Client1, go to Configure Build Path -> Projects. Add ServerClient1Common. Remove all references to Server Project.
For Server, go to Configure Build Path -> Projects. Add ServerClient1Common. Remove all references to Client1 Project.
You should now have a lot of missing classes/imports. Try to solve them one by one.
At the end, you should be able compile the 3 projects and to obtain the jars you mentioned.
PS: Other strategies (like one uber-project with different build targets, or 3 projects with entwined ant/maven builders) are messier. There is maybe one exception - another way of splitting the classes, but I do not know if it applies to you: client1.jar, client1-interface.jar, client2.jar, client2-interface.jar, server.jar, server-interface.jar. This way you could use 3 projects with each having two target jars. To run client2.jar you will need server-interface.jar
Have a separate Eclipse project for each JAR that you're going to create. Then set up the dependencies on the "Projects" tab of the Build Path, for each of the top level projects. So, the "server" project will have "server-client1-common" and "server-client2-common" listed as required projects. And so on.
I've seen this model used by a number of different organisations, and I've always thought that this was the "industry accepted" way of doing it. It just works!
We are building a small application using different architectural layers such as domain, interface, infrastructure and application. This follows the Onion DDD model. Now I am wondering if there is any benefit in splitting the application into a multimodule maven project. As far as I can see now it seems to make things more difficult than needed. The entire application will be deployed as a single WAR file into a Tomcat container.
Splitting your application makes sense for the following:
When a certain part of the project needs to have new functionality or bug fixes, you can simply focus on that module and run just the tests for it. Compiling a fraction of all the code and running just the related tests speeds up your work.
You can re-use the code from the modules across different projects. Let's assume your project contains some well-written generic-enough code for mail sending. If you later have another project that need mail sending functionality, you can simply re-use your existing module or build upon it (in another module by adding it as a dependency).
Easier maintainability on the long run. Maybe now it seems like a small project. In a few months things might look different and then you'll need to do more refactoring to split things into logical units (modules).
Conceptual clarity (as added by Adriaan Koster).
Concerning the WAR: You can have an assembly module which puts things together and produces a final WAR file from all the related modules.
Initially, this may seem as more work, but in the long-run, modularized projects are easier to work with and to maintain. Most sane developers would prefer this approach.
Using multiple modules forces you to have a hierarchy of dependencies. You have one module which is standalone and doesn't depend on any other of your modules. You have another which only depends on that. It might appear harder than allowing anything to depend on anything else but this approach results in a mess of dependencies which is hard to fix later.
If you are trying to follow a layered model I suggest you place each layer in a different module. This will ensure you are not tempted to break the model.
Short answer: today it is small, tomorrow it will bigger and more complicated to maintain, reuse, extend, integrate with other system and so on
As far as I know, Maven do little help for WAR dependencies. As you are talking about single WAR, this should never be a problem.
You can separate java classes into several "jar" submodules, but if you split the WAR project into several smaller WARs, using some kind of "overlapped" packaging things get complicated.
Just information, one of our projects, it contains too many web pages, so we decided to split it into several WAR submodules, however, the session is not shared between different WARs deployed, and we are not going to use Kerberos stuff. At last, we modified a lot sources of Glassfish, Jetty, MyFaces, etc. To make them resolve web.xml stuff inside JARs. And converted the whole project to Facelets 2.0 (to avoid the dependency of JDK tools.jar and custom resource handler), the only reason is to change the WAR submodules to JAR submodules, and move all webapp/pages into class resources. So the conclusion, Maven does great job for JAR dependencies, but no WAR or single WAR.
EDIT You can put applicationContext.xml in one of the base submodule, and import it by classpath:com/example/applicationContext.xml. Also Spring 3.0 do have annotation supports, you can make spring auto scan them instead of declaring them all in the xml.
Spliting your project into multiple maven projects is useful if you want to reuse your classes in another project or if your projects are deployed in different configurations.
Maybe think of a webservice - if you are hosting the server, you could build a project for your domain classes (models) and your endpoint interfaces that could be used by server and client. The server would be another project that is build to a WAR.
To develop further clients the first project could be used, too.
Use a parent project for dependency management on common projects (like logging) and different profiles and build configurations.
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.