understanding - How should I structure a Java application, where do I put my classes?




understanding java project structure (6)

A few thoughts:

  • Very few files in the root of the tree. On a large team, set permissions so that no one can add new files to the root of the tree, without some kind of authorization.

The default workspace will contain:

  • Tools contains all executable code required to build & run unit tests, including your custom tools and scripts (perhaps assuming that Visual Studio and PowerShell are already installed on the machine).

  • ReferencedAssemblies has things you pick up from somewhere else, including things you buy or download and things someone on the team wrote but isn't part of this project.

    • If available, source code should be in here, too, so you can service it yourself. (If not available, you're taking a big riks.)
  • Source - all the source code, including project files.

  • Documents - items that are not used as part of the build, but are necessary for the proper functioning of the development effort.

  • Binaries - bits that have been shipped to customers, including .PDBs and other artifacts necessary for servicing. (On small projects, I fork the sources for each release, but normally a tag/label is a better choice.)


Elsewhere (e.g. $/personal) have a place for each person to do with as they please ($/personal/USERNAME). For example, my side projects go here.

First of all, I know how to build a Java application. But I have always been puzzled about where to put my classes. There are proponents for organizing the packages in a strictly domain oriented fashion, others separate by tier.

I myself have always had problems with

  • naming,
  • placing

So,

  1. Where do you put your domain specific constants (and what is the best name for such a class)?
  2. Where do you put classes for stuff which is both infrastructural and domain specific (for instance I have a FileStorageStrategy class, which stores the files either in the database, or alternatively in database)?
  3. Where to put Exceptions?
  4. Are there any standards to which I can refer?


I've really come to like Maven's Standard Directory Layout.

One of the key ideas for me is to have two source roots - one for production code and one for test code like so:

MyProject/src/main/java/com/acme/Widget.java
MyProject/src/test/java/com/acme/WidgetTest.ava

(here, both src/main/java and src/test/java are source roots).

Advantages:

  • Your tests have package (or "default") level access to your classes under test.
  • You can easily package only your production sources into a JAR by dropping src/test/java as a source root.

One rule of thumb about class placement and packages:

Generally speaking, well structured projects will be free of circular dependencies. Learn when they are bad (and when they are not), and consider a tool like JDepend or SonarJ that will help you eliminate them.


To expand on what Mendelt Siebenga suggested, I would also add a web directory (for JSP files, WEB-INF, web.xml, etc).

Tests should go in a folder named test that is a sibling of the main src folder - this way your unit test classes can have the same package name as the source code being tested (to ease with situations where you want to test protected methods or classes, for example... see the JUnit FAQ for this, and this question also on Where should I put my test files?).

I haven't had much use for it myself, but a Maven project will also create a resources folder alongside the src folder for non-source code that you want to package/deploy along with the main source code - things such as properties files, resources bundles, etc. Your mileage may vary on this one.


Recommended Source Control Directory Structure?

I usually have

Project Directory
  src - actual source
  doc - documentation
  lib - libraries referenced from source
  dep - installation files for dependencies that don't fit in lib
  db  - database installation script

In work with Visual Studio, I'm not sure if this works the same in the java world. But i usually put stuff in different project folders in src. For each source project there's a separate test project. Build files go in the main project directory. I usually put a README there too documenting how to setup the project if it needs more than just checking out.

EDIT: This is the structure for a single working checkout of the project. It will be duplicated for each branch/tag in your revision control system (remember, in most SVN system, copies are cheap). The above example under Subversion would look like:

/project
    /trunk
        /src
        /doc
        /...
    /branches
        /feature1
            /src
            /doc
            /...
        /feature2
            /src
            /doc
            /...

What is the optimal VSTF source structure? Are there any best practices?

Here is one that I like:

  • Private; all of the current system deliverables
    • Documentation; a rollup of all the documentation across the solutions that make up the product, output would be MSDN style documentation from Sandcastle
    • Common; Visual Studio SLN that contains all the projects that are common across all the other solutions.
    • Tools; Visual Studio SLN that contains all the projects whose output is a tool. Example might be a console app that performs a set of administrative task on the larger system
    • Developer; each developer has their own folder which they can use for storing whatever they want
      • Specific Developer (1..n); this contains any build settings, scripts, and tools that this specific developer chooses to store in the source control system (they can do whatever they want here)
    • Specific Deliverable Solution (1..n); Visual Studio SLN that contains all the projects for a specific major deliverable
      • Common; solution folder that contains Visual Studio Projects that are shared within the current solution
      • UI; solution folder that contains Visual Studio Projects that define user experience
      • DataLayer; solution folder that contains Visual Studio Projects that define a data access layer
      • Services; solution folder that contains Visual Studio Projects that define web services
      • Tools; solution folder that contains Visual Studio Projects that define tools specific to this deliverable (executable utilities)
      • Tests; solution folder that contains Visual Studio Projects that contain unit tests
  • Public; all of the external dependencies associated with the system (eg. 3rd party libraries)
    • Vendor; dependencies provided by a specific vendor
  • Build; Visual Studio SLN that contains code associated with the build of the project, in our case mostly custom MSBuild tasks and Powershell scripts
  • Target; each successful build of the product as well as point releases
    • Debug; all of the debug builds that are output from weekly builds and continuous integration. Developers do not manually manage this directory
      • Build Number; a directory that corresponds with the current build number
        • Solution Output; a directory that contains all the build output for each of the projects in a given solution
    • Release; all of the release builds that are output manually when a milestone is reached
      • Build Number; a directory that corresponds with the current build number
        • Solution Output; a directory that contains all the build output for each of the projects in a given solution

Note: All solutions will have a Tests folder and unit test projects.





architecture