All Java projects I have seen use a folder structure that follows the package structure. This results I large number of folders that do not contain any files.
So for example packages start with com.mydomain.mysystem.myutility. This would result in a folders src\com, src\com\mydomain, src\com\mydomain\mysystem that do not contain any files. Most likely the myutility will also only contain only folders.
Most likely there will also be a project folder that contains the name myutility so the complete folder path could be myutility\src\main\java\com\mydomain\mysystem\myutility\otherfolder
This practice is very common but it makes we wonder how useful it is. What is benefit compared to the situation where these extra folders are not created? Using for example myutility\src\main\java\otherfolder
It seems to be just as valid but it saves everybody the extra navigation steps. I can compile Java source files with both approaches just fine.
In a project typically all source is in com\mydomain\mysystem. What is the benefit of putting those 'empty' folders in all projects?
Just to be clear, I am not questioning the usefulness of package structure. Also Maven is clear.
The question is why we use the empty folders that are typically the same throughout the repository for an organisation.
The source (and class) files are organized like that so that the Java compiler (and the runtime environment) can find them.
When the Java compiler compiles your class, it needs the source or class file of each class that your class depends on, so that it can check that the class exists, that all methods are called with the correct arguments, etc. Also, if it find a source file but not class file, or if the class file is older than the source file, it will compile the source file of the class you use.
The compiler could of course just check all subfolders of your class path, or even the entire disk, but that would take a lot of time. Because of this convention the compiler only has to check a single subfolder for each classpath entry. Of course you can think of different solutions to this problem, but the people at (then) Sun thought this was the best option.
Of course, the above also applies to the class files which are loaded at run-time, so also the class files are stored in a similar folder structure.
Note also that Java applications and libraries are often packaged as a Jar file (which basically is a zip file with the same folder structure inside), so in many cases they appear as a single file in the file system.
The reason it is done this way is to prevent conflicts and ensure that classes can be uniquely identified. This means that if 2 classes have the same name they can still be loaded via different imports.
The safest way to do this is by using a domain name, which is by its nature unique:
com.google.<classname> for example.
Your approach will work and saves a few empty folders but is not scalable.
Related
it's been a while since i've been working with java and especially with eclipse. My professor sent me a huge folder with many subfolders and subsubfolders, that mainly contain .class java files. Now I'm supposed to work on these files, but i just can't seem to figure out how to get all of them working. I found a few solutions for single class files, but i have a whole folder hirarchy here that i want to work on.
I hope you can help me - I read something about decompiling? How does that work?
Note that I have around 50 different files here that need to be accessible.
Thank you very much!
I suppose the class you are attending is not something like "CS 902 - Reverse Engineering", because if that was the case, you would know what to do with the .class files.
So, one of the following holds true:
Your professor has made a mistake, and instead of sending you the java files, he/she sent you the class files instead.
Your professor sent you the entire project, which contains both .java and .class files, and for some reason you have only managed to find the .class files, while the .java files are there, and you just haven't found them. Unfortunately, the convention in the java world is to store .class files in a subfolder under the project root, so if you copy the project folder, you are copying .class files together with everything else.
Your assignment is to write new code which makes use of classes and interfaces supplied by your professor, but your professor does not want you to have the source code of those files. In this case, you can still work with the .class files, because the public definitions contained therein are parseable by Eclipse and usable in your project, without any reverse engineering. So, what you need to do is to find a way to tell eclipse that these .class files form a "Class Library" which is supposed to be used by your project, and then go ahead and develop new .java files making use of the library. I don't remember how this is done in Eclipse, but you should be able to find it out by yourself, or look it up, or perhaps someone else might post a how-to answer. However, at this point we do not even know whether this is in fact what you need to do.
You can use a java decompiler like JD-GUI, you can find it at http://jd.benow.ca/ . This is a very handy tool to have when you want to view a decompiled version of your jar. There are plugins available for eclipse and intellij as well.
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.
I'm working on some Java code in eclipse. Code is contained in a single class called Adder, which in Eclipse is in the package org.processing. The first thing in the class file is the line
package org.processing
Q1) What, exactly is this line doing? Why is there, what's it's role.
The code runs fine in eclipse, however, when I move into the workspace if I go to the src/org/processing/ folder in src, compile with javac Adder.class when I try and run using java Adder I get the following error
java.lang.NoClassDefFoundError: Adder (wrong name: org/processing/Adder)
On the other hand, if I compile from src using
javac org/processing/Adder.java
and I can run it from src using java org.processing.Adder but STILL not from within the processing directory.
Q2) Does this mean that compilation is always relative to directory structure?
Finally, if I remove the package org.processing line from the start are the .class file I can compile and run from within the .class file's directory.
Q3) Why is all this the way it is? I can fully understand enforcing a directory structure for code development, but once you're in bytecode this seems a bit over the top, because now I can (apparently) only run the bytecode from one director (src) using java org.processing.Adder. Now, I'm sure I'm missing the point here, so if someone could point out what it is, that would be great.
The compiler has to be able to find related source code files when compiling. This is why the package and directory structure must agree for source code. Similarly, the JVM must be able to find referenced .class files. So the same directory structure is required at runtime. It's no more complex than that.
Q1) The issue here is that once you got into the folders that represent your package hierarchy, you set that as the working directory. It's gonna look inside of org/processing/Adder for the path org/processing/Adder (essentially looking from the root for org/processing/Adder/org/processing/Adder). You need to call it from the root with the full path. The purpose of packages is A: to organize related classes into groups. And B: Along with A, classes in package Foo.bar can't view private classes in other packages, as they are like internal classes for that package, only the package they're in can use them
Q2) Yes
Q3) The paths are used as a basic structure for the JVM to know where exactly the class files (each containing their bytecode) are. If you change where you call it from, your basically trying to change the location for the JVM to look for the class files, but their true location hasn't changed.
The short answer - Packages help keep your project structure well-organized, allow you to reuse names (try having two classes named Account), and are a general convention for very large projects. They're nothing more than folder structures, but why they're used can burn beginners pretty badly. Funnily enough, with a project less than 5 classes, you probably won't need it.
What, exactly is this line doing? Why is there, what's it's role.
The line
package org.processing
is telling Java that this class file lives in a folder called /org/processing. This allows you to have a class which is fully defined as org.processing.Processor here, and in another folder - let's say /org/account/processing, you can have a class that's fully defined as org.account.processing.Processor. Yes, both use the same name, but they won't collide - they're in different packages. If you do decide to use them in the same class, you would have to be explicit about which one you want to use, either through the use of either import statements or the fully qualified object name.
Does this mean that compilation is always relative to directory structure?
Yes. Java and most other languages have a concept known as a classpath. Anything on this classpath can be compiled and run, and by default, the current directory you're in is on the classpath for compilation and execution. To place other files on the classpath, you would have to use another command-line invocation to your compilation:
javac -sourcepath /path/to/source MainClass.java
...and this would compile everything in your source path to your current directory, neatly organized in the folder structure specified by your package statements.
To run them, as you've already established, you would need to include the compiled source in your classpath, and then execute via the fully qualified object name:
java -cp /path/to/source org.main.MainClass
Why is all this the way it is?
Like I said before, this is mostly useful for very large projects, or projects that involve a lot of other classes and demand structure/organization, such as Android. It does a few things:
It keeps source organized in an easy-to-locate structure. You don't have objects scattered all over the place.
It keeps the scope of your objects clear. If I had a package named org.music.db, then it's pretty clear that I'm messing with objects that deal with the database and persistence. If I had a package named org.music.gui, then it's clear that this package deals with the presentation side. This can help when you want to create a new feature, or update/refactor an existing one; you can remember what it does, but you can't recall its name exactly.
It allows you to have objects with the same name. There is more than one type of Map out there, and if you're using projects that pull that in, you'd want to be able to specify which Map you get - again, accomplished through either imports or the fully qualified object name.
For Q1: The package declaration allows you to guarantee that your class will never be mistaken for another class with the same name. This is why most programmers put their company's name in the package; it's unlikely that there will be a conflict.
For Q2: There is a one-to-one correspondence between the package structure and the directory structure. The short of it is that directories and packages must be the same, excepting the package is usually rooted under a folder called src.
For Q3: Once it's compiled, the class files will probably be in the appropriate folders in a jar file. Your ant or maven tasks will build the jar file so you won't really have to bother with it beyond getting the ant task set up the first time.
I have com.company.database.mysql and com.company.database.sqlite. I only want to include com.company.database.mysql.
My code was organized in folders (eg com/company/database/mysql) but now I want to have it flattened (eg com.company.database.mysql) so that I can include just the mysql code.
Eclipse doesn't seem to let me do this. It complains that the package is wrong "The declared package "com.company.database.mysql" does not match the expected package "" It only works if I unflatten it (ie com/company/database/mysql).
How can I get eclipse to work with code in folders named com.company.etc instead of subfolders?
The problem is that the Java compiler interprets periods in package declarations to be separate directories. So, if your file DataAccess.java is like:
package com.company.database.mysql
public class DataAccess {
}
The compiler will insist that this file be in a directory named mysql which is in a directory name database which is ... In other words your original directory structure:
src/main/java
com
company
database
mysql
That is the reason for the error. However you don't have to go to the lengths that you are just to exclude some of the source. You can manage your project's source path (Project properties > Build path) and exclude one or more directories.
You can't. The dots in the path are directory separators.
For compiled code you can store the class files in a jar. The directory path inside the jar will still be the the tree you have created.
If you really want to flatten the structure use a different character than a period. However, I would not recommend that you use such a non standard solution.
That's not an Eclipse thing -- that's part of the rules of Java, and thus is how pretty much every Java compiler works. It expects your files to be in folders named like com/company/database/mysql, and it's pretty rigid about that.
In order to change that, you'd need to either get rid of the package name, get rid of the dots in it, put your classes into a jar (which would still contain that directory structure, but you could just have com.company.database.mysql.jar rather than a folder), or change Java itself.
It's the convention of the java compiler that your source files are laid out in a particular way (depending on the platform/filesystem). If I understand you correctly, I think you are trying to go against that convention.
From http://docs.oracle.com/javase/6/docs/technotes/tools/windows/javac.html:
You should arrange source files in a directory tree that reflects
their package tree. For example, if you keep all your source files in
C:\workspace, the source code for com.mysoft.mypack.MyClass should be
in C:\workspace\com\mysoft\mypack\MyClass.java.
as weSuppose that I am creating a Java project with the following classes
com.bharani.ClassOne
com.bharani.ClassTwo
com.bharani.helper.HelperOne
com.bharani.helper.support.HelperTwo
with files put immediately under the folder 'src'
src/ClassOne.java
src/ClassTwo.java
src/HelperOne.java
src/HelperTwo.java
and compile them using the command
$ javac -d classes src/*.java (assuming that classes directory exists)
The compiler compiles these files and put the class files in appropriate sub-directories inside the 'classes' directory like this
classes/com/bharani/ClassOne.class
classes/com/bharani/ClassTwo.class
classes/com/bharani/helper/HelperOne.class
classes/com/bharani/helper/support/HelperTwo.class
Because the spec mandates that the classes should go inside appropriate directory structure. Fine.
My question is this: When I use an IDE such as Eclipse or NetBeans, they create the directory structure for the source code directory ('src' directory here) as well. Why is that? Is it mandatory? Or, is it just a convention?
Thanks.
Mainly convention. It makes sense for the source to mirror the binary structure.
Also, if you have two classes with the same name (but in different packages), how would you store the source if not in different directories?
Keeping the source in just one folder is fine for small projects, but once you have a larger project (hundreds of classes), grouping the source into packages makes things far more manageable.
Is it mandatory?
No
Or, is it just a convention?
Yes, to reflect your package structure in your source tree.
I always thought that Java's package is a little bit broken:
it seems to be hierachical, but it is not.
it is a simple (unique) prefix to define seperate plain namespaces.
I thought it was mandatory, but your experience suggests otherwise. Either way, it's just common sense, right? Large projects have so many source files - why make life more complicated by having different structures for your source and your class files?