1

I know there are multiple posts on similar problems, so please be kind with me. I am asking for suggestions I have not thought of and for good advice.

I have a java "project" that is structured in a server-client pattern. There are some classes that are common to both parts but most of it is either server (backend and control logic) or client (GUI). To not write one monolithic application (where the client depends on JDBC jars) I decided to split the project into multiple eclipse projects:

  • proj_server (where JDBC is needed)
  • proj_client
  • proj_common
  • proj_test

In proj_test there is some code to test parts of the client/server. I setup eclipse such that both server and client depend on the common module.

Now I use git to manage all these eclipse projects. My first thought was to manage all parts in separate repos as suggested by git. But I have the problem that I loose the relation of the different commits: Any modification in the proj_common will typically reflect some data type modification. This makes the new version incompatible with old commit in the other projects.

I then thought of several possibilities:

  1. Using of git submodules
  2. Using of git subtree
  3. Using of a single git repository that contains the modules together
  4. Using different repositories and adding regularly tags to the commits to keep track of the relations

The solution 1 has the problem that it is quite heavy to maintain. Especially if you want to check in multiple small modifications you have to go multiple times "around the folders" to add/commit and then pack it all in the main repository up.

The subtree method might work well as far as I have read with a bunch of scripts to manage the git calls. The main disadvantage is that subtree fits perfectly if most work is done in the main repository and updates to the imported repos happen occasionally. If the updates happen merely in the subprojects the history of the main projects gets quite crumpled. On branching it might get complicated.

The solution number 3 is my favourite solution so far as everything is kept tight and branching is done without any problem.

The solution 4 is mainly what is done now, but no tag have been created yet (pre-alpha, thus no sense in creating tags). As the project grows this might get also very nasty and error-prone.

What would you suggest? One of the given solutions or did I miss the one perfect solution?

Edit:

I have found the following related posts: a, b, c and d. Unfortunately the big picture is not clear. In a (second answer!) and d the advice tends towards multiple repositories in different files. But they do not explicitly state how to manage the relationship of the different commits. That is you cannot go for the running configuration at Jan 10th 2013 for example without looking at the history explicitly for all subprojects. In b solution 3 is suggested. In c a comparision is made. They first had something like multiple manually managed projects but then migrated to solution 3.

In all these Q&As the first two solutions were at most mentioned but not suggested by the answering persons. In the net you can find much about git submodule that tells you that you get quite much overhead by it (e.g. here or here).

The problem is (as far as I can see) that in practice I will have not only one project with some reference to one or more libraries. In this case (hopefully) the library would not change regularly and the coding takes place in the "main" repository. In this case all the advances solutions (subtree, submodules, ...) might be very useful.

In my case on the contrary I have only a dummy master repository that holds the four subprojects in sync. These subprojects themselves are under high development. So it is a critical part that the contribution to the different online (sub)projects is straight forward. Not much additional magic with git.

In another site they suggest solution 1 but I am unsure what their main development goal is: The main repository or the imported library.

I want to avoid getting into trouble and later have to migrate to another system. Thus I ask for advice of somebody who might have done similar things.

  • Pro tip: if you know similar questions already exist but do not address your specific need, it helps to link to them and maybe explain the difference. This shows that you did your research and helps to define your question better. – user22815 Sep 4 '14 at 12:34
  • I added some links to the question. – Christian Wolf Sep 4 '14 at 13:26
4

For this kind of work, I suggest you to learn about Maven which deals with dependency compatibility (among a lot of other things).

With Maven, you could for example use one of these two ways:

Either the "standard" way: by creating a Nexus repository which you will feed with a compiled jar of each version of your common package and to fully exploit maven/nexus the version(s) of JDBC you use. Each time you build your project from any commit, the versioned config file will be read and will use the good revision of your library "common".

(I say Nexus, but there are others software doing the same thing, I've also heard of one named Artifactory).

Or, you could make a more complicated script which, when you build your server or client project, go download the source of your library on your "common" repository and build it.

Maven may seems a bit overkill and is (in my opinion) a pain to learn alone, but it's handy, powerful, and is the professional standard in Java and works seamlessly with Eclipse.

As for the Maven usage, the Nexus way is (depending on your scripting skill) a bit heavier to init, but more standard, easy to scale with your project, and can be used for all your other future projects.

If you're working in a professional context, I strongly advise to look for a colleague knowing it to help you mavenize your project.

  • Please correct me, but: As far as I understood Maven, it is a tool to manage he build process and dependencies, not the source code. My question is purely related to how to manage the source code "correctly". – Christian Wolf Sep 4 '14 at 10:54
  • @ChristianWolf: Does your proj_common produce a jar file of its own, or do proj_server and proj_client refer to java files that happen to be located in the tree of proj_common? – Bart van Ingen Schenau Sep 4 '14 at 11:21
  • @BartvanIngenSchenau: proj_common just holds some classes for the other projects. Thus no jar will be generated; only for server and client projects. – Christian Wolf Sep 4 '14 at 11:38
  • 1
    In fact, the "trick" is you will have build configuration file which will handle dependency, and theses files will be versionned with your code. So your current handling with 4 depots is a "right" way, you just need to handle the fact what your package "common" is a library. To do that you could use Maven, and eventually Nexus as explained in the completed answer. – GaelFG Sep 4 '14 at 12:07
  • Maven is really excellent. ---it especially imposes conventions (better to be followed) / "best practices," like a project having src/main/java and src/test/java and so on. This would means splitting your proj_test. But after maven you can integrate git and do things like having different versions for client and server, by using maven depency version numbers like 1.0. – Joop Eggen Sep 4 '14 at 12:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.