Modular Maven projects and multiple Git repositories - java

I have separated the code that I have been making up to this point from a single maven project to multiple maven projects. The projects that I have ended up with can be used by future projects, they are pretty much libraries. I have been using a single Git repository up to this point since everything was in one project. However after the modularisation I wonder if I should create a Git repository for each Maven project. I think that is the correct way to do it, but I would like to hear what others think of that. Since the projects could work as standalone components they also deserve their own Git repository? Another option would be to develop all the projects in the same Git repository for the project that I currently work on.

Since the projects could work as standalone components they also deserve their own Git repository?
This is actually one of the main criteria for defining a git repo, which will represent a coherent group of file with its own independent history (including its set of branches and tags)
This has the additional advantage that some other project depending on some but not all your components won't have to clone the full unique git repo (which would contain everything, included components not needed).
That other project can clone and benefit from the exact subset of components needed.
This is called the component approach, as opposed to the system approach.

Related

Is it best practice to place Java project directly under the Source Code Repository

Any pros and cons or creating additional folders under a repository ?
The example scenario below elaborates the question further:-
e.g. Say we are using Git as an SCM.
Option 1
myrepository/my-favorite-maven-project-1
|____pom.xml
/my-favorite-maven-project-2
|____pom.xml
Option 2
myrepository/SomeFolder1/my-favorite-maven-project-1
|____pom.xml
/SomeFolder1/SomeFolder2/my-favorite-maven-project-2
|____pom.xml
I would like to get pros and cons with the Option 1 and Option 2.
Putting multiple maven projects under a single git repository makes sense if both of the projects are in fact modules of each other and they are released/branched at the same time.
It's a mistake if you're moving from SVN where you've had a single large SVN repo and lots of projects next to each other though. The reason is, SVN branches/tags work at the folder level, but in Git they work at the repository level. So if you're branching/releasing project-1 and project-2 separately, they should be in separate Git repositories.
The corollary is that there's very little point in having a top level folder SomeFolder1 because there's almost no reason you'd ever have a SomeFolder2.

Jar Dependencies in GitHub

I'm setting up a new Java project on GitHub, and I'll have some Apache Commons libraries as dependencies.
What are the best practices to establish that my project needs those jar files? Should I upload the dependencies to my GitHub repository (ugly)? Or use a Maven-like tool for that?
Or is there a way to link a file in another git repository? Apache provides git repositories for they libraries. They are read-only, but I'm o.k. with that, since I just want to use the jars. The bad thing is that they contain all the sources, and I just care about the compiled jar. It seems we can't git submodule just a file.
The two approaches are:
declarative and component-based, where you declare (describe) what components (jars, exe, other binaries) you need for your project to (compile, execute, deploy, etc.), and you use a third-party tool (like Maven/Nexus) to bring those components on demand.
So they aren't versioned in your repo. They are declared/described (like in a pom.xml, if you were to use Nexus)
See also "Difference between Git and Nexus?".
inclusive and system-based, where you complete your project with other project sources/binaries, in order to get in your repo everything you need right after the clone step (no need to call a third-party tool or to do anything: every other part of your system in there).
With Git, especially if those "other parts" are in a git repo (like the apache libs one), then you would declare those sub-repos as submodules of your main repo.
That way, all you keep in your main repo is a special entry (gitlink, mode 160000) referencing a specific SHA1 of another repo (but you can make that submodule follow a branch too, a bit like svn external).
And with sparse checkouts in submodules (as in this example), you even can update those modules for them to checkout only the part of the repo you want (like just the jars, not the sources).
Note that you aren't supposed to store any delivery that you would produce (like jars of your own) in your GitHub repo.
You can associate those deliveries to GitHub releases though.

Build multiple java projects with dynamic dependencies

I have multiple java projects in a folder. Also there is a second folder with libraries, that might be used as build dependencies from the projects. The projects may also have dependencies to other Projects. What's the best approach to build all projects ?
In other words I want to build the projects without explicit telling their dependencies.I think the biggest problem is the dependecy between the projects.
There are multiple build systems that are available that you may use. Maven has a complete dependency system built into it. Almost all third party open source jars are directly accessible via the World Wide Maven repository system. Basically, you describe the jar you need (groupId, artifactId, and version) and Maven will automatically fetch it for you. Not only that, but Maven also will build your project without having to create a build file. Instead, you have to describe your project in a project object model (a pom.xml file) and Maven will download everything you need, including all compilers, etc.
Almost all new projects use Maven, but Maven has a few downsides:
Since you don't control a build process, it can sometimes feel like poking a prodding a black box to get the build to work the way you want.
Documentation can be scant -- especially if you're moving beyond basic Java compiles.
You usually have to arrange your project in a specific layout. For example, source files should go under src/main/java while JUnit tests are under src/test/java. You don't have to follow the recommended layout, but then you'd have to modify the pom.xml file this way and that to get your build to work. That defeats the whole purpose of the pom.xml in the first place.
If you already have another build system setup (like Ant), you lose everything. There's no easy way to move from Ant to Maven.
The other is called Ant with Ivy. Ivy uses Ant for building, but can access Maven's world wide repository system for third party dependencies. It's a great compromise if you already are heavily invested in Ant. I also find Ant with Ivy to be better documented than Maven (although that's not too difficult). There's an excellent chapter going over the basics of Ivy in Manning Publication's Ant in Action.
With either process, I would recommend that you build a company wide Maven repository using either Nexus or Artifactory. This way, any proprietary third party jars (like Oracle jars) can also be stored in your company wide Maven repository since they won't be in the standard World Wide Maven repository.
By the way, if this is a company wide effort, and you are moving multiple Ant projects into Ivy, I have an Ivy project I use in Github that makes things easier.
Oh, there's a third possibility called Gradle which I know nothing about. I also believe it can use the World Wide Maven repository. It's based on Groovy which is based on Java syntax, and that's about all I can say. Maybe others can fill you in on the details. The Gradle group contends it solves a lot of problems of both Ant/Ivy and Maven.
Whatever tool you use, if you have various projects interdependent, you need to be clear on the independent ones which will be built first before building the dependent projects. You need to have a clear dependency structure for your projects.
You can do this with Apache Ivy. You can lay out the locations for you common libraries, define published artifacts and inter-dependencies in an ivy.xml document in each project, and let a top-level Ant build with the Ivy tasks figure out what the build order should be based on those dependencies.

Share entities between multi-projects

I have 3 Java projects with the same entities.
I want to share entities between these projects because entities can evolve during the development phase.
We are thinking about building a jar with entities and sharing it using Maven (with a repository).
Maybe you have another solution ?
I also can recommend to use Maven to share code between projects.
Here are some tips to get started:
Use a Maven Repository Manager such as Nexus. It will help you to
create a stable development environment.
Every developer (also the Continuous Integration Server user) should configure their settings file to use your Maven Repository
Manager. Don't specify your repositories in the POMs, confiugre them
only in your Maven Repository Manager.
http://www.sonatype.com/books/nexus-book/reference/maven-sect-single-group.html
Use the dependencyManagement and pluginManagement elements of your parent POMs to specify all versions of the plugins and dependencies
you are using. Omit these versions in the other POMs (they will
inherit them from the parent POM).
I also recommend to use different POMs for multi-module builds and parent POMs.
If you want to share common interfaces, classes, functionality or components, Maven is the way to go. In addition to the dependency management, you also get the added bonus of a standard project layout that will simplify things. Easy integration with most common continuous integration servers and a standard release process are further benefits.
Definitely take a look at Maven!
making an own JAR-library is definitely a good solution.
The jar-file is easy to distribute via dependency management (maven, ivy, gradle ..)
The jar is versioned
The projects using the library can be tested against a certain verion. Otherwise it may gets a problem if you change enties and forget to change a depending project. -> integration tests
Regards
Entities are the representation of a given object am I correct? If so the default mechanism implemented by Java is Object serialization - http://en.wikipedia.org/wiki/Serialization. In the case of jar files if an entity changes you would have to change jar once again each time as well. It may be tedious.
Geneate a standard war file in roo.. But then change it's package to jar file.
Then from any standard war file you can just deploy this jar (Ill use the jar as a maven dependency). Ill maintain a unique named applicationConext like pizzaShop-applicationContext.xml and like pizzaShop-applicationContext-jpa.xml. so from a parent spring project I can stack up various roo projects in this fashion.
Ill also keep their generated webapps folder to allow for the generator to work more easily. (This means I have to open up the pom.xml and keep changing it back to jar). Also helps with cut and paste fodder for non roo generated war files web.xml entry additions.
Seems like it may be a confusing point about roo.. You can just mix and match these jars as you would any spring project. They function like self contained units of springness and work fine sitting side by side with other spring jars all under the same webapp/web.xml context.
Its tedious but still better then writing spring code by hand.

Egit working directory vs. projects in Eclipse

I'm a long time Eclipse user but new to Git/Egit. Recently I've been trying to use Egit because I want to use GitHub to collaborate with a number of projects. The projects I want to work on are not Eclipse-specific projects but I'd still like to set up a workflow so that I can work on them in Eclipse.
It seems that there are a number of things that need to fit together:
The remote repository (on GitHub)
The local repository (somewhere on my filesystem)
The Git working directory
The Eclipse project that I want to work in (including stuff outside the source tree like Eclipse project files, Maven config, build folders etc.)
How do these relate to each other and what should be my workflow?
In particular:
Do I actually need a local repository or can I just work directly with the remote repository (like with SVN)?
Can the Git working directory also be the Eclipse project? Or is this a bad idea?
What should my workflow of push/pull/fetch etc. normally be?
If I use Maven for dependency management in the Eclipse project, but don't want all the Maven-specific stuff to get committed to SCM, can this work?
Guess I'm loking for some sound advice from someone who's successfully made this work!
Do I actually need a local repository or can I just work directly with the remote repository (like with SVN)?
Git is all about working on a local repository and pushing elsewhere when necessary.
Can the Git working directory also be the Eclipse project? Or is this a bad idea?
If it lines up this way, then yes. This is how I've managed my projects.
What should my workflow of push/pull/fetch etc. normally be?
You push when you feel you have made enough commits (sometimes only 1) that are worth pushing. You pull when you want to work with changes that other people have pushed.
See gitworkflows for the official doc on different types of workflows.
If I use Maven for dependency management in the Eclipse project, but don't want all the Maven-specific stuff to get committed to SCM, can this work?
Usually you just commit the pom.xml. Anything else is a user specific setting. Although, if I clone your repository and can't do a "mvn compile", then there's something wrong.

Categories

Resources