Hopefully this is a question that only needs a fairly quick answer, but I haven't had much luck finding something online that is in terms I understand!
Quite simply, I'm working on my first real project in Java, a text adventure, (using IntelliJ IDEA) and I was just wondering if I need to be splitting my code into modules? So, for my monsters, should I keep all of my monster classes within a module called Monsters, or can I just keep it in the same module?
I only ask because; a) I wasn't sure whether it was a done thing in order to keep the project tidy and b) When I tried to create a Monster module, I received a warning telling me that the files in this module wouldn't be accessible from the rest of the program, which seems to defeat the object to me...
Many thanks in advance for any advice!
I believe you are referring to IntelliJ's concept of a module. As stated on their page:
A module is a discrete unit of functionality which you can compile, run, test and debug
independently.
Modules contain everything that is required for their specific tasks:
source code, build scripts, unit tests, deployment descriptors, and
documentation. However, modules exist and are functional only in the
context of a project.
So, modules should not be referencing the source code from other modules. They should essentially be completely different units.
As in thecbuilder's answer, you should look into using Java's packaging system instead.
By modules if you mean packages, then its a good habit to keep related classes in one package and distributing unrelated classes in different packages.
And to the thing, that the classes wouldn't be accessible, you'll have to make them public to access them from different packages.
More on package structuring :
http://www.javapractices.com/topic/TopicAction.do?Id=205
http://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html
https://stackoverflow.com/a/3226371/3603806
For access specifiers :
Taken from : http://www.go4expert.com/articles/java-access-specifiers-t28019/
Related
first of all - I am not sure if cucumber support this, but is it possible to define features in different module than in one that contains feature files?
Given real life example:
Let's say I want to have module called 'carcore',
Then let's say I want to have module called 'Volkswagen',
and other one called 'Ford'.
Is it possible that I will put feature deffinition files for common features in 'carcore' module but keep feature diffinition files specific for vokswagen or ford in their own modules?
I am using gradle to sew this modules together. It is more or less simple. Though when Cucumber annotations are introduced, it is not that easy. Cucumber is not able to find feature definitions in other modules. I was not able to find any relevant and useful reading, so if anyone can help me or point me into right direction I would be very glad.
Cucumber is designed so that you have one World for your features, and in that world each thing you talk about should have a unique name and a single definition. It deliberately chooses to not have any kind of name-spacing. The rationale behind this is that Cucumber is a tool for describing business behaviour not for programming.
What you are doing with your modules is programming, and what you seem to reflecting is HOW your program is implemented, but HOW has no place in Cucumber scenarios; they should be written way before you think about HOW to do things. Scenarios should only be about WHAT the business wants and WHY they want this.
What you can do with your modules idea is push it down your stack, into the step definitions or better yet modules that define calls that your step definitions can use. Now because you are in a programming language you have the power to program in whatever way you need.
Finally Ford and Volkswagen are brands of Car. Whilst you might use the names as examples having a module for an individual brand seems wrong at any level.
It is done automatically as with any other classes.
Cucumber will pick up automatically any feature definition files that are in defined dependencies.
My IDE didn't picked up the relation between feature definition file and feature itself, so it got me confused.
I am writing here because of desperation caused by refactoring a GWT project.
My first try:
After I read all the praises of the refactoring tool from Eclipse ( I am using it as IDE) I simply right clicked on a module ( what a fool i was ) and use the refactoring option. My project became unusable.
First Conclusion:
Found out that I need to start with the classes and then go up and refactor a module at a time.
Second try:
Refactored some classes, worked fine until I messed something related to a ui.xml file. Project unusable!
Second Conclusion:
Be careful at the ui.xml files!
Third try:
Went pretty well, but I got ahead of myself and tried to remove some comments or replace class names in comments. Predictable result : project unusable!
Third Conclusion:
Try again!
Forth try:
Fail!
Fifth try:
Fail!
You get the picture.
Can someone experienced with GWT please offer some guidelines about the mystical realm of refactoring?
GWT has some rules based on naming conventions (e.g. the two interfaces for GWT-RPC, the *.ui.xml files and the class that uses them through UiBinder, the files related to ClientBundle or ImageBundle methods, the *.properties files for I18N), so failing to respect them when renaming/moving one class/file will break it.
GWT also sometimes references classes by name in non-Java files (#eval in the *.css of a CssResource, or in *.ui.xml files), non-Java portions of classes (JSNI) or string literals (e.g. in #ProxyForName and #ServiceName). Failing to update them all will break the build.
Because a tool makes it easy to refactor does not mean you should let it do it blindly: it's just a tool, you have to understand what it does and double-check it (hint: check the box in Eclipse that forces a preview before applying the refactoring) so it doesn't do too much or too few.
I want to understand the packing methodology in real big projects.
Suppose we have a package com.abc.xyz, and for this, we really have a path like com/abc/xyz.
Is it possible to have multiple same package names in different directory structure like:
Directory path 1:
/home/user1/project/module1/src/java/com/abc/xyz
Directory path 2:
/home/user1/project/module2/src/java/com/abc/xyz
And finally when we create jar for the whole project, do we create jar with respect to com directory?
When some application uses import com.abc.xyz, how does it know which directory path's package it is referring to?
And finally, is there any good book/resource which gives guidelines about packaging, how to divide project into modules, package names etc.
One more thing, does a project have common package base name like in above case:
com.abc.xyz (e.g., org.apache.hadoop ).
Thanks,
Vipin
Packages created in different source directories are the same package, as far as the classloader is concerned. It also doesn't matter if the class files are in the same jar or different jars. The JVM does not discriminate based on where the source code came from.
(Of course if you have two jars loaded by different classloaders those are going to be treated differently.)
One case where you frequently have different source trees with the same package is when you have tests in a different directory (using the usual Maven convention where the code is under src/main/java and the tests are in src/test/java) but with the same package as the code that they exercise. These tests are able to exercise protected and package-private parts of the code under test, because they're in the same package as that code.
The path of directories inside the jar should start at the root of the package. (The topmost directory should be /, then one called com or org or whatever, etc.) Packages do form a tree-like structure, and when you put your code in a filesystem you end up having a hierarchy of packages, but the language itself doesn't recognize a concept of "subpackage" (except that packages that start with java are special and get special treatment by the classloader).
Organizing code into packages is done differently by different people. Some people like to organize their code by layer (putting all controllers in one package, all services in another package, all daos in still another package), some like to organize their code by feature.
Package-by-layer is the conventional way of organizing code, it seems to be the preferred practice in the Java community. One consequence of this is that when code implements a feature as a vertical slice at right angles to the package structure (as it may require a new controller endpoint, maybe a new service method, etc.), so closely-related bits of code for the same feature end up scattered across different directories. The Java Practices website makes an interesting case for package-by-feature:
Package By Feature Package-by-feature uses packages to reflect
the feature set. It tries to place all items related to a single
feature (and only that feature) into a single directory/package. This
results in packages with high cohesion and high modularity, and with
minimal coupling between packages. Items that work closely together
are placed next to each other. They aren't spread out all over the
application. It's also interesting to note that, in some cases,
deleting a feature can reduce to a single operation - deleting a
directory. (Deletion operations might be thought of as a good test for
maximum modularity: an item has maximum modularity only if it can be
deleted in a single operation.)
Here's an SO question asking about package by feature or layer.
Yes, you could make duplicate packages in separate directories, but I can't think of a good reason to do it. If the classes within the package have the same names you can certainly get namespace collisions. I am not sure what "module" means in this context but I'd recommend
com.abc.module1.xyz
com.abc.module2.xyz
instead. Those would be distinct packages to the classloader. You can still keep your /home/user1/project/module1/ directory structure up front, that doesn't matter.
From 2 modules you will have two seperate jar files: module1.jar and module2.jar. Both will be loaded into ClassLoader when application starts.
When some application uses import com.abc.xyz, how does it know which directory path's package it is referring to?
Classloader will handle that. http://www.javaworld.com/article/2077260/learn-java/the-basics-of-java-class-loaders.html
If you trying to develop multi module application i recommend you to check Maven tool:
http://maven.apache.org/
Why maven? What are the benefits?
For guidance for package organization you can just google 'java packages' phrase.
http://www.tutorialspoint.com/java/java_packages.htm
https://www.facebook.com/Niranthara-Jaya-JavaSocial-Media-Apps-Software-Project-Management-244119296136021/
This page is for people who wish to know how to work with real world Java projects. Send a message to this page and check out the articles.
I have an app written with GWT and GAE where every supported city has its own app. Clearly this is not the best way to manage the map so I want to merge them all into one app. Currently my app is at the urls sub1.myapp.com, sub2.myapp.com, sub3.myapp.com, etc, and I want them to be at myapp.com/sub1 ,myapp.com/sub2, etc. All the supported cities share common code, so I'm going to put all the that code in one module, and have a different module for each piece of unique code block. Is this going about it the right way? How will the different modules interact?
Also, I currently have JSPs at sub1.myapp.com/listofsomesort and I would like to move these to myapp.com/sub1/listofsomesort. Is there a simple way to accomplish this?
By making a module with EntryPoint for each old application, in one and the same application. Each module has one 'welcome page' which you can put in different directories. All the shared code can go into another module. The shared code can be used by the inherit setting in other modules.
The only thing I bumped into was that when you deploy to GAE, ALL modules should have an entry point, also the library modules. I solved it by adding a dummy EntryPoint to them, that does nothing, but still searching for a better solution. See my question at How to deploy GWT Project containing GWT modules without entry points with Eclipse GAE plugin?.
This seems like the job for Code Splitting :) It might require some changes in the structure of your code, though - depends how tightly coupled your classes are. A compile report should tell you if your code splits up nicely, or if not, where the connections are.
Whats the best practice for setting up package structures in a Java Web Application?
How would you setup your src, unit test code, etc?
You could follow maven's standard project layout. You don't have to actually use maven, but it would make the transition easier in the future (if necessary). Plus, other developers will be used to seeing that layout, since many open source projects are layed out this way,
There are a few existing resources you might check:
Properly Package Your Java Classes
Spring 2.5 Architecture
Java Tutorial - Naming a Package
SUN Naming Conventions
For what it's worth, my own personal guidelines that I tend to use are as follows:
Start with reverse domain, e.g. "com.mycompany".
Use product name, e.g. "myproduct". In some cases I tend to have common packages that do not belong to a particular product. These would end up categorized according to the functionality of these common classes, e.g. "io", "util", "ui", etc.
After this it becomes more free-form. Usually I group according to project, area of functionality, deployment, etc. For example I might have "project1", "project2", "ui", "client", etc.
A couple of other points:
It's quite common in projects I've worked on for package names to flow from the design documentation. Usually products are separated into areas of functionality or purpose already.
Don't stress too much about pushing common functionality into higher packages right away. Wait for there to be a need across projects, products, etc., and then refactor.
Watch inter-package dependencies. They're not all bad, but it can signify tight coupling between what might be separate units. There are tools that can help you keep track of this.
I would suggest creating your package structure by feature, and not by the implementation layer. A good write up on this is Java practices: Package by feature, not layer
The way I usually organise is
- src
- main
- java
- groovy
- resources
- test
- java
- groovy
- lib
- build
- test
- reports
- classes
- doc
I usually like to have the following:
bin (Binaries)
doc (Documents)
inf (Information)
lib (Libraries)
res (Resources)
src (Source)
tst (Test)
These may be considered unconventional, but I find it to be a very nice way to organize things.
The way i usually have my hierarchy of folder-
Project Name
src
bin
tests
libs
docs
One another way is to separate out the APIs, services, and entities into different packages.