In Java, where in the package/source hierarchy should resources be placed? - java

Say I have developed a game, and placed it in the package structure:
com.dxmio.games.breakout
Where then is the 'best practice' place to put resources like audio and images that the game uses?

You can always adopt a standard Maven approach to your project and put all application source files in:
{home}/src/main/java/com/dmxio/games/breakout
and then your resources live in:
{home}/src/main/resources/com/dmxio/games/breakout
and your tests then live in:
{home}/src/test/java/com/dmxio/games/breakout
This structure is a standard convention to structuring projects in the Maven world. It brings a lot of advantages with it, which you may want to look at. You can check out the resources section here: Apache Maven Guides - How do I add resources to my JAR
Alternatively :) the other answer's approach here is just fine...

I have seen this handled in a number of different ways:
Place your resources directly in a subdirectory under com/dmxio/games/breakout (e.g. /com/dmxio/games/breakout/images/foo.gif and /com/dmxio/games/breakout/images/bar.gif)
Place your resources in a jar along with your class files (e.g. foo.gif and bar.gif bundled in breakout.jar)
Place your resources in a separate 'resources jar' in a subdirectory under com/dmxio/games/breakout (e.g. foo.gif and bar.gif bundled in /com/dmxio/games/breakout/images/images.jar)
I tend to favor the last option.
You can then use the java.lang.Class.getResource() method to retrieve your resources.

Related

What's the most conventional folder for outputting resources if you need them strictly within build target?

We all know "inputable" resources are by convention in src/main/resources and src/test/resources, but what about the runtime outputted ones? Is it better to use target/ or target/{classes,test-classes}or simply give up and try to use external path even if it complicates things for security reasons? I've been brainstorming a bit regarding that decission as shown following, but need the help of more experienced users that can shed more light.
PROS of target/{classes, test-classes}
If maven engineers architected the convention by moving resources to target/classes instead of target/resources I assume they had a good reason in mind for preferring it
It organizes input and output resources on the same base folder
It makes test and main outputs independent, so no conflict can appear if names are equal
IT makes much conventional and secure to define the relative route of the resource ( by ClassLoadeR().getResource() or etProtectionDomain().getCodeSource().getLocation() [no file globs]
It makes much easy to centralize output behavior, in case our idea is having a function for UPSERTing resources, we need to use resolution for sufolder as they are not in the same path (so prepend /classes/ to the relative route but / for an original resource)
I think due to the previous ones, there can be a bit of confusion when using parent poms, because there is a target for both parent and module, but only one classloader URL -> /target/classes
It works flawlessly if using the classes directory as the base classpath of the app, when executing directly from console.
PROS of target/
When packaging the app as a library, you don't need to deal with an output folder inside the jar.
I have been told that maven doesn't like too much anything strictly outside of target/, but have no further info
A central folder can be used when executing tests in case production code generates files and tests works with them also
Perhaps a single target at parnet pom's level makes files easier to share among different modules
So how do you usually handle these sort if things?
I am sure some of you have a more authoritative question
So typically if you are allowing resources to be pulled in from outside of your Jar you need to either hard-code that relative path or read it from fixed config file. You would then document this when you release your application.
For example, Eclipse has a folder specially for plugins. You can drop new plugins here and know that Eclipse will pick them up and know what to do with them.
In my applications, I usually define a conf directory that sits at the same level as the executable Jar. I'll put any log4j and other such post-compile config files there.
You mention security issues, which is a good thing to think about. When you are pulling in data, always try to do some sort of sanity checking (make sure a directory exists, a zip file isn't corrupt, etc). Since you can't control what comes in, make sure you do as many checks as you can on the program side.

In Java, should I be creating a new Package, Folder, or Source Folder?

There are a couple of questions on SO that sort of hit this, but I am totally new to Java development and I don't know the correct way to approach this.
I have a C# solution, containing two projects (my app, and a unit test project) and within the app, most things are put into folders eg. Interfaces, Exceptions etc.
I am trying to recreate this in Java / Eclipse, but I don't know how. I ended up with lots of packages, which sounds really bad. I also tried adding a source folder but that ended up being outside of the package.
Could anyone point me in the right direction?
Namely, which of those should I use to represent my unit test project/set of unit tests, and subfolders which exist just for organising stuff.
Edit: It also says use of the default package is not advised. What should I be doing?
Edit 2: Here is what it looks like. Does this look vaguely correct? My original C# solution is on the right.
In a typical java eclipse project, you will have one or more source folders (for example one for app code, one for your unit tests).
Each folder contains a package tree, typically starting with your base package, for example com.mycompany.myapp.
In order to avoid name collisions, packages names are usually start with the domain name of the entity who is the author of the code, starting with the top-level-domain and going backwards (more general to more specific). That way, each class fully qualified name is unique. For example if google creates a class named List, it will be known as com.google.List, and it will not enter in conflict with the existing java.util.List interface.
You can have a unlimited number of packages inside this base package, for example :
com.mycompany.myapp.persistence
com.mycompany.myapp.domain
com.mycompany.myapp.services
com.mycompany.myapp.web
It all depends on your project and the way you want to organize your code and your classes.
At the logical level, packages are named with dots as separator. They contain java classes.
At the physical on disk level, each package is a directory. The java classes are contained in .java files (most frequently one class per file).
In Eclipse a "source folder" is a folder inside your project that is known to Eclipse to contain java source files. It will be compiled included in the output (for example JAR file) when you build your project.
In Eclipse, you usually view them at the logical level, showing packages. When you tell Eclipse to "create a new package", it will create the directory for you. For example, if you tell it to create the com.mycompany.myproject package, it will automatically create a com folder containing a mycompany folder containing a myproject folder.
In java source tree structure must match package structure
so foo.bar package must be laid out in
src/foo/bar
Also default package may not be advised - but you can still use it - better to put things in a package though
In java different project development structure are flowed according to type of project.
So as you are new to java and Eclipse so it's better to install maven plugin and create maven project and choose a archetypes according to your project type like a standalone or web based.
The maven plugin will create the project structure including packages,test packages source folder etc. You can get more about project structure from 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.

Where to put script for generating java sources in maven structure?

In one project (http://jodd.org) we have some classses generated by python scripts. Those are some big classes that has utility methods with similar behavior for all primitives and Object; we just wanted to simplify life and avoid potential errors made by repeating similar code.
Also note that this scripts are invoked manually, so we do NOT need any automation process etc.
We are mavenizing the project, and these scripts fall in the src/main/resources folder. Therefore, they become part of distributed jar with other resources, which is what we want to avoid.
What would be the standard maven location for these files; so they not become part of the distro jar? Is it src/main/scripts or src/main/python, or we should simply put them outside, in e.g. etc folder?
I think a good place to put python scripts is in src/main/python as you described. Doing so, they won't be copied to the final jar. I use similar approach with some native codes written in C in my projects.

Java distribuion as jar file containg config, libs and deps

I am developing a framework that needs a lot of stuff to get working. I have several folders inside of my Eclipse project that are needed
[root]
- config
- src
- lib
- serialized
Also there are important files like the log4j.properties and the META-INF dir inside the src directory.
I wonder if there is a way to distribute one JAR containing all essential files so my gui will just have to import one jar. I guess that I have to exclude the config folder in order to make the framework configurable.
I also wonder, if there is a way to move for example the log4j.properties to the config dir so that I have one config folder containg all needed configurations?
Thanks for help and advise on this matter!
Marco
Yes, but not really. You can take all your dependencies, unpack them and simply merge them into a bigger jar. This is what the maven jar plugin does if you make a jar with dependencies. The only problem is that this might result in conflicting files (suppose two of your dependencies contain a log4j.properties). This is one of the problems when doing the above with some of the spring libraries for instance.
I think someone actually wrote a classloader that allows you to bundle the whole jar inside of your jar and use it as is. I'm not sure how mature that is though and can't at the moment recall the name.
I think you're better off distributing all your dependencies separately. Setting up the classpath is a bit of a pain but surely java programmers are used to it by now. You can add dependencies to the Class-Path header in your manifest file, in simple cases. Bigger libraries have to rely on the classpath being set up for them though.
As to the second part of your question, probably dropping the conf/ directory under META-INF is enough for its contents to be picked up. I'm not sure about this. I'm fairly sure it will always be picked up if you put its contents at the top level of the jar. In any case, this is a distribution problem. You can easily have a conf/ directory inside your source tree and have your build scripts (whatever you might be using) copy the files in it to wherever is most convenient.
As to your users configuring. Try to establish some conventions so they have to configure as little as possible. For things that must be configured, it's best to have a basic default configuration and then allow the user to override and add options through his/her own configuration file.
In terms of the resources, it is possible except that if you do that you are not going to be able to load resources (non class files) from the filesystem (via a file path).
It's likely that you're currently loading these resources from the file system. Once in the jar you need to load them as class path resources via the class.getResourceAsStream or similar.
As for the dependent jars you may have, it's common practice for these to be placed as extra jars on the classpath. I know it's complicates things but developers are used to doing this. The nature of the java landscape is that this is inevitable. What the spring framework for example does is supply a bundled zip file with the core jar and the jar dependencies included.
Is your library going to be used in an EE context or an SE context? If it is an EE context then you really don't have to worry about configuration and class path issues as the container takes care of that. In an SE context it is a lot more tricky as that work has to be done manually.

Recommended Source Control Directory Structure?

I am going to be using Subversion for source control on a new J2EE web application. What directory structure will you recommend for organizing code, tests and documentation?
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
/...
I found some old questions here on SO that might be interesting for you:
Whats a good standard code layout for a php application
Contains a link to an article on Scalable and Flexible Directory Structure for Web Applications (focus on PHP, though)
How to structure a java application, in other words: where do I put my classes?
Structure of Projects in Version Control
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.
I use Eclipse for creating J2EE web applications and this will create the following project structure:
WebAppName\
\lib
\src
\tests
etc...
I would then create an SVN folder on our trunk called WebAppNameProject. Within this folder I would create folders called WebAppNameSource, Documentation etc. Within the WebAppNameSource folder I would place the project source generated by Eclipse. Thus I would have the following folder structure in SVN:
\svn\trunk\WebAppNameProject
\WebAppNameSource
\lib
\src
\tests
etc...
\Documentation
Hope this helps.

Categories