the number of class files in a java package constant - java

I am new to java.My friend asked me this question today And i am looking for an answer to it.
How to make the number of class files in a package, constant?
i.e., even though one can access that package,they should not be able to add any new class to the exisiting package.

You want sealed packages. Once sealed, all classes from a package must come from the same JAR file. It basically boils down to adding the package to the manifest:
Name: myCompany/myPackage/
Sealed: true
See Sealing packages within a jar file

This is called sealing the package and works on the level of jar files.
From the official trail:
Packages within JAR files can be optionally sealed, which means that all classes defined in that package must be archived in the same JAR file. You might want to seal a package, for example, to ensure version consistency among the classes in your software.
To clarify: Since the classes must come from the same jar file, no one can add classes to your package, since the new classes wouldn't come from your jar file.

Related

redeclaring interfaces in multiple jar files

I have several interfaces (e.g. mypackage.IMyInterface) which are implemented in multiple software modules. On the other hand, I use a build script that puts these modules in seperate jar files (for versioning reasons).
Would it be "ok" to include the same interface in each individual jar file.
Just to make myself perfectly clear. The package mypackage would be included in all jar files, and they would all have a copy of the exact same mypackage\IMyInterface.class file.
I've seen this practice in some open-source jar files. But I'm not sure if it's good practice or if it happens by accident.
This is a bad practice.
A package shouldn't be shared between different jars.
At least an interface (or a class) should not be copied in multiple jars.
The best is to extract common interfaces (and classes) and put them in a separate jar and import that jar everywhere it is used.
So going from this situation:
mylibfirst.jar (jar1):
com.mygroup.mylib.MyCommonInterface
com.mygroup.mylib.MyClass1
mylibsecond.jar (Jar2):
com.mygroup.mylib.MyCommonInterface
com.mygroup.mylib.MyClass2
To the following:
mylibfirst.jar (Jar1, using mylib.jar):
com.mygroup.mylib.first.MyClass1
mylibsecond.jar (Jar2, using mylib.jar):
com.mygroup.mylib.second.MyClass2
mylib.jar (Jar3):
com.mygroup.mylib.MyCommonInterface

Why do java source files require package declarations?

I think I am failing to understand java package structure, it seemed redundant to me that java files have a package declaration within, and then are also required to be present in a directory that matches the package name. For example, if I have a MyClass.java file:
package com.example;
public class MyClass {
public static void main(String[] args) {
System.out.println("Hello, World");
}
}
Then I would be required to have this file located in com/example, relative to the base directory, and I would execute java com.example.MyClass from the base directory to run it.
Why wouldn't the compiler be able to infer the package name by looking at the directory structure? For example, if I compiled the file from the base directory javac com\example\MyClass.java, I am not understanding why the MyClass.java wouldn't implicity belong to the com.example package.
I understand there is a default package, but it still seems that the package declaration in the source file is redundant information?
As you (implicitly) acknowledged, you are not required to declare the name of a package in the case of the default package. Let us put that quibble aside ...
The reason for this seeming redundancy is that without a package declaration, the meaning of Java1 source code would be ambiguous. For example, a source file whose pathname was "/home/steve/project/src/com/example/Main.java" could have 7 different fully qualified names, depending on how you compiled the code. Most likely, only one of those will be the "correct" one. But you wouldn't be able to tell which FQN is correct by looking at (just) the one source file.
It should also be noted that the Java language specification does not require you to organize the source code tree according to the packages. That is a requirement of a (large) family of Java compilers, but a conformant compiler could be written that did not require this. For example:
The source code could be held in a database.
The source code could be held in a file tree with random file names2.
In such eventualities, the package declaration would not be duplicative of file pathnames, or (necessarily) of anything. However, unless there was some redundancy, finding the correct source "file" for a class would be expensive for the compiler ... and problematic for the programmer.
Considerations like the above are the practical reason that most Java tool chains rely on file tree structure to locate source and compiled classes.
1 - By this, I mean hypothetical dialect of Java which didn't require package declarations.
2 - The compiler would need to scan the file tree to find all Java files, and parse them to work out which file defined which class. Possible, but not very practical.
Turn the question on its head:
Assume that the package statement is the important thing - It represents the namespace of the class and belongs in the class file.
So now the question is - Why do classes have to be in folders that match their package?
The answer is that it makes finding them much easier - it is just a good way to organize them.
Does that help?
You have to keep in mind that packages do not just indicate the folder structure. The folder structure is the convention Java adopted to match the package names, just like the convention that the class name must match the filename.
A package is required to disambiguate a class from other classes with the same name. For instance java.util.Date is different from java.sql.Date.
The package also gives access to methods or members which are package-private, to other classes in the same package.
You have to see it the other way round. The class has all the information about itself, the class name and the package name. Then when the program needs it, and the class is not loaded yet, the JVM knows where to look for it by looking at the folder structure that matches the package name and the class with the filename matching its class name.
In fact there's no such obligation at all.
Oracle JDKs javac (and I believe most other implementations too) will happily compile your HelloWorld class, no matter what directory it is in and what package you declare in the source file.
Where the directory structure comes into the picture is when you compile multiple source files that refer to each other. At this point the compiler must be able to look them up somehow. But all it has in the source code is the fully qualified name of the referred class (which may not even have been compiled yet).
At runtime the story is similar: when a class needs to be loaded, its fully qualified name is the starting point. Now the class loader's job is to find a .class file (or an entry in a ZIP file, or any other imaginable source) based on the FQN alone, and again the simplest thing in a hierarchical file system is to translate the package name into a directory structure.
The only difference is that at runtime your "standalone" class too has to be loaded by the VM, therefore it needs to be looked up, therefore it should be in the correct folder structure (because that's how the bootstrap class loader works).

Using classpaths

I plan on becoming a certified Java programmer and am studying from the Sierra-Bates book. I had a question about classpaths. Do classpaths need to find only the supporting classes of the class I'm running/compiling, or the supporting classes and the class itself? Also, when I'm getting classes in packages from classpaths, is it legal to just put the adress of the file(the path to it), instead of putting it's root package. Thanks.
1 - a classpath has to give access to each class that needs to run in your program. That would include the main class and any classes it calls and those they call. If there is some code in one of those classes that is never called, in many cases, you don't need to have the classes referenced by the uncalled code.
2 - you have to put the root of the packages in the classpath. So a class "com.bob.myprog.Main" would need to have the class path point to the folder where the "com" package/folder lies. It will need to contain a "bob" folder and "bob" will need to contain a "myprog" folder with "Main.class" in it.
Classpath has to contain both the supporting classes and the class itself.
However, sometimes you can run a single file without specifying classpath (and it will work).
As specified in http://docs.oracle.com/javase/tutorial/essential/environment/paths.html :
The default value of the class path is ".", meaning that only the
current directory is searched. Specifying either the CLASSPATH
variable or the -cp command line switch overrides this value.
Therefore, if you have a class MyClass compiled in the current directory, the following will work:
java MyClass
while pointing classpath to another directory will lead to an error (classpath no longer contains MyClass):
java -cp lib MyClass
When you have a class in a package, it is not enough to put the address to the class file in the classpath. According to SCJP Sun Certified Programmer for Java 5 Study Guide:
In order to find a class in a package, you have to have a directory in
your classpath that has the package's leftmost entry (the package's
"root") as a subdirectory.

Java: Point of subdirectories

First of all: I'm not entirely familiar with Java, and the few things I know I have learned while playing with Java.
However, there is something I have noticed in pretty much any Opensource Java project - the use of alot of subdirectories for the sources, which usually look like so:
./src/main/java/com/somedomainname/projectname/sourcefile.java
Now, why so many subdirectories? what's the deal with the domainname?
The domain name is used for the package name - so that file would be for the class
com.somedomainname.projectname.sourcefile
where com.somedomainname.projectname is the package.
Conventionally, source file organization mirrors the package layout. The normal Java compiler doesn't actually enforce directory structure (although some IDEs such as Eclipse will complain if you put things in the "wrong" directories) but it does force public classes to be in a file with the same name. Non-public classes can go in any file, but conventionally the filename matches the class name there, too. It makes it very easy to navigate to any class without any prior knowledge.
The Java language specification doesn't say that a compiler must enforce the convention for public classes; it explicitly says that it can though. See section 7.2 of the JLS for more details.
This directory structure is used as a convention that shows where the library is from and separates it from other sources.
One reason to use this structure is that is the standard used by Maven.
Maven is a build tool that helps to manage the dependencies of a project. Maven is designed for convention over configuration, so you will often see this directory structure to make it work with Maven.
Maven specifies that the directory structure start with /src/main/java for Java files, and the rest is based on the naming convention for namespaces.
The use of the domain name in the path is to prevent class collisions. If 2 different libraries both supply a class with the same name, the domain name namespace allows them to both be used.
A Java package is a mechanism for
organizing Java classes into
namespaces similar to the modules of
Modula. Java packages can be stored in
compressed files called JAR files,
allowing classes to download faster as
a group rather than one at a time.
Programmers also typically use
packages to organize classes belonging
to the same category or providing
similar functionality.
...from http://en.wikipedia.org/wiki/Java_package
subdirectories as an organizational tool so that you don't just have one directory with tons of java files. The reason you often see a domain name is that conventionally people derive java package names from their domain names in order to prevent collisions with other developers. So although we both might have a util.Stringutil class, if I name mine com.mydomain.util.Stringutil and yours is com.yourdomain.util.Stringutil, we can have a project containing both classes without a collision.
There is an interesting read on java packages and directories in the newer O'Reilly book Java: The Good Parts (starting at the bottom of page 46).
...the required interaction between the package system and the filesystem
is both regrettable and a pain...
This is meant as a standard to define unique locations for java source code. It is convention to follow this package structure, which is why you see it everywhere. It's not required to do it that way - you can name your packages whatever you want. It is very commonplace to follow this convention, however.
package prefix.organization.project.ClassName;
package prefix.organization.project.package.ClassName;
package prefix.organization.project.package.subpackage.ClassName;
When storing Java source code files, each part of the package name translates into a subdirectory. So the same three classes shown above would be located in the corresponding directories off the main classpath.
prefix/organization/project/ClassName.java
prefix/organization/project/package/ClassName.java
prefix/organization/project/package/subpackage/ClassName.java
When compiling by hand, be sure that the main classpath directory is the current directory or is within the classpath in order that the source code files can be found.
As for the src/main/java part of it, it seems this comes from Maven. I've never used that software. I don't understand why they would need so many, since my projects (I use Eclipse) just have a src folder there instead.
./src/main/java/com/somedomainname/projectname/sourcefile.java : Decomposed
src/main/java
this is the directory that needs to be passed to the javac compiler stating where the source code for compilation can be found.
1.1 src/test/java
this is where the unit test classes should be kept.
1.2 src/main/resources and src/test/resources
these are the corresponding directories where resources such as properties files should be kept.
1.3 Separate output directories.
main and *test * classes and resources should be compiled to their own separate output directories. Maven uses target/classes and target/test-classes. When you jar your compiled class files for distribution, you don't want to include test classes and test resource files.
com/somedomainname/projectname
this directory structure corresponds to the package declaration in the classes found in projectname i.e. package com.somedomainname.projectname
SourceFile.java corresponds to the class name that it defines, and it should by convention start with an uppercase character see http://www.oracle.com/technetwork/java/codeconvtoc-136057.html
Also in the link above you will find out that the default package naming convention uses the domain name in reverse.
The Java Language Specification defines a package naming convention that says that package names should include a domain name, as it provides a globally-rooted namespace.
The source files need to be in subfolders that match the package name, because the Sun Java compiler, javac, enforces strongly encourages it. Additionally, many other build tools and IDEs also either strongly encourage or require that the source .java files are stored in paths that match the package.

Java project structure explained for newbies?

I come from a .NET background and am completely new to Java and am trying to get my head around the Java project structure.
My typical .NET solution structure contains projects that denote logically distinct components, usually named using the format:
MyCompany.SomeApplication.ProjectName
The project name usually equals the root namespace for the project. I might break the namespace down further if it's a large project, but more often than not I see no need to namespace any further.
Now in Java, you have applications consisting of projects, and then you have a new logical level - the package. What is a package? What should it contain? How do you namespace within this App.Project.Package structure? Where do JARs fit into all this? Basically, can someone provide a newbies intro to Java application structure?
Thanks!
Edit: Some really cracking answers thanks guys. A couple of followup questions then:
Do .JAR files contain compiled code? Or just compressed source code files?
Is there a good reason why package names are all lower case?
Can Packages have 'circular dependencies'? In other words, can Package.A use Package.B and vice versa?
Can anyone just show the typical syntax for declaring a class as being in a package and declaring that you wish to reference another package in a class (a using statement maybe?)
"Simple" J2SE projects
As cletus explained, source directory structure is directly equivalent to package structure, and that's essentially built into Java. Everything else is a bit less clear-cut.
A lot of simple projects are organized by hand, so people get to pick a structure they feel OK with. What's often done (and this is also reflected by the structure of projects in Eclipse, a very dominant Java tool) is to have your source tree begin in a directory called src. Your package-less source files would sit directly in src, and your package hierarchy, typically starting with a com directory, would likewise be contained in src. If you CD to the src directory before firing up the javac compiler, your compiled .class files will end up in the same directory structure, with each .class file sitting in the same directory and next to its .java file.
If you have a lot of source and class files, you'll want to separate them out from each other to reduce clutter. Manual and Eclipse organization often place a bin or classes directory parallel to src so the .class files end up in a hierarchy that mirrors that of src.
If your project has a set of .jar files to deliver capability from third-party libraries, then a third directory, typically lib, is placed parallel to src and bin. Everything in lib needs to be put on the classpath for compilation and execution.
Finally, there's a bunch of this and that which is more or less optional:
docs in doc
resources in resources
data in data
configuration in conf...
You get the idea. The compiler doesn't care about these directories, they're just ways for you to organize (or confuse) yourself.
J2EE projects
J2EE is roughly equivalent to ASP.NET, it's a massive (standard) framework for organizing Web applications. While you can develop your code for J2EE projects any way you like, there is a firm standard for the structure that a Web container will expect your application delivered in. And that structure tends to reflect back a bit to the source layout as well.
Here is a page that details project structures for Java projects in general (they don't agree very much with what I wrote above) and for J2EE projects in particular:
http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html
Maven projects
Maven is a very versatile project build tool. Personally, my build needs are nicely met by ant, which roughly compares with nmake. Maven, on the other hand, is complete-lifecyle build management with dependency management bolted on. The libs and source for most of the code in the Java world is freely available in the 'net, and maven, if asked nicely, will go crawling it for you and bring home everything your project needs without you needing to even tell it to. It manages a little repository for you, too.
The downside to this highly industrious critter is the fact that it's highly fascist about project structure. You do it the Maven way or not at all. By forcing its standard down your throat, Maven manages to make projects worldwide a bit more similar in structure, easier to manage and easier to build automatically with a minimum of input.
Should you ever opt for Maven, you can stop worrying about project structure, because there can only be one. This is it: http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html
A package in Java is very similar to a namespace in .Net. The name of the package essentially creates a path to the classes that live inside it. This path can be thought of as the class's namespace (in .Net terms) because it is the unique identifier for the specific class you want to use. For example if you have a package named:
org.myapp.myProject
And inside it you had a bunch of classes:
MyClass1
MyClass2
To specifically refer to those classes you would use:
org.myapp.myProject.MyClass1
org.myapp.myProject.MyClass2
The only real difference between this and .Net (that I know of) is that Java organizes its "namespaces" structurally (each package is a distinct folder) whereas .Net allows you to scope classes using the namespace keyword and ignores where the document actually lives.
A JAR file is roughly analogous to a DLL in most cases. It is a compressed file (you can open them with 7zip) that contains source code from other projects that can be added as dependencies in your application. Libraries are generally contained in JARs.
The thing to remember about Java is that is is very structural; WHERE files live is important. Of course there is more to the story then what I posted but I think this should get you started.
A package is much like a .Net namespace. The general convention in Java is to use your reversed domain name as a package prefix so if your company is example.com your packages will probably be:
com.example.projectname.etc...
It can be broken down to many levels rather than just one (projectname) but usually one is sufficient.
Inside your project structure classes are usually divided into logical areas: controllers, models, views, etc. It depends on the type of project.
There are two dominant build systems in Java: Ant and Maven.
Ant is basically a domain-specific scripting language and quite flexible but you end up writing a lot of boilerplate stuff yourself (build, deploy, test, etc tasks). It's quick and convenient though.
Maven is more modern and more complete and is worth using (imho). Maven is different to Ant in that Maven declares that this project is a "Web application project" (called an archetype). Once that is declared the directory structure is mandated once you specify your groupId (com.example) and artifactId (project name).
You get a lot of stuff for free this way. The real bonus of Maven is that it manages your project dependencies for you so with a pom.xml (Maven project file) and correctly configured Maven you can give that to someone else (with your source code) and they can build, deploy, test and run your project with libraries being downloaded automatically.
Ant gets something like this with Ivy.
Here are some notes about Java packages that should get you started:
The best practice with Java package names is to use the domain name of the organisation as the start of the package, but in reverse, e.g. if your company owns the domain "bobswidgets.com", you would start your package off with "com.bobswidgets".
The next level down will often be the application or library level, so if it's your ecommerce libraries, it could be something like "com.bobswidgets.ecommerce".
Further down than that often represents the architecture of your application. Classes and interfaces that are core to the project reside in the "root" e.g. com.bobswidgets.ecommerce.InvalidRequestException.
Using packages to subdivide functionality further is common. usually the pattern is to put interfaces and exceptions into whatever the root of the subdivision is and the implementation into sub packages e.g.
com.bobswidgets.ecommerce.payment.PaymentAuthoriser (interface)
com.bobswidgets.ecommerce.payment.PaymentException
com.bobswidgets.ecommerce.payment.paypal.PaypalPaymentAuthoriser (implementation)
This makes it pretty easy to pull the "payment" classes and packages into their own project.
Some other notes:
Java packages are tightly coupled to directory structure. So, within a project, a class with a Package of com.example.MyClass will invariably be in com/example/MyClass.java. This is because when it is packaged up into a Jar, the class file will definitely be in com/example/MyClass.class.
Java packages are loosely coupled to projects. It is quite common that projects will have their own distinct package names e.g. com.bobswidgets.ecommerce for ecommerce, com.bobswidgets.intranet for the intranet project.
Jar files will container the class files that are the result of compiling your .java code into bytecodes. They are just zip files with .jar extension. The root of the Jar file is the root of the namespace hierarchy e.g. com.bobswidgets.ecommerce will be /com/bobswidgets/ecommerce/ in the Jar file. Jar files can also container resources e.g. property files etc.
A package is a grouping of source files that lets them see each others' package-private methods and variables, so that that group of classes can access things in each other that other classes can't.
The expectation is that all java classes have a package that is used to disambiguate them. So if you open a jar file in your project, like spring, every package starts with org.springframework. The classloaders don't know about the jarfile name, they use only the package.
There's a common practice of breaking things down by type of object or function, not everybody agrees about this. Like Cletus posted here, there's a tendency to group web controllers, domain objects, services, and data access objects into their own packages. I think some Domain-Driven Design people do not think this is a good thing. It does have the advantage that typically everything in your package shares the same kind of dependencies (controllers might depend on services and domain objects, services depend on domain objects and data access objects, etc.) so that can be convenient.
Okay so in java you have three different types of access to a classes member functions and variables
public
protected
package-private
and private
All classes in the same package can see each others public, protected, and package-private elements.
Packages are not hierarchical in the system. Usually they are organized in a hierarchical way, but as far as runtime is concerned com.example.widgets is a completely different package from com.example.widgets.cogs
Packages are arranged as directories, which helps keep things organized: your file structure is always similar to your package structure.
They are planning on adding a module system to Java in JDK7 (called Project Jigsaw) and there is an existing module system called OSGi. These module systems will/can give you a lot more flexibility and power then the simple package system.
Also, package names are usually all lower case. :)
To answer the example sub-question:
package com.smotricz.goodfornaught;
import java.util.HashMap;
import javax.swing.*;
public class MyFrame extends JFrame {
private HashMap myMap = new HashMap();
public MyFrame() {
setTitle("My very own frame");
}
}
Do .JAR files contain compiled code? Or just compressed source code files?
They might contain both, or even totally different kinds of files like pictures. It's a zip archive first of all. Most often you would see JARs that contain class files, and those which contain source files (handy for debugging in your IDE if you use third party code) or those that contain javadoc (sourcecode documentatin), also handy if your IDE supports tooltipping the documentation when you access the lib's functions.
Is there a good reason why package names are all lower case?
Yes there is a good reason for package names to be written in lowercase letters: There is a guideline which says that only classnames are written with a capital letter in front.
Can Packages have 'circular dependencies'? In other words, can Package.A use Package.B and vice versa?
Packages do not use each other. Only classes do. And yes that might be possible but bad practice.
Can anyone just show the typical syntax for declaring a class as being in a package and declaring that you wish to reference another package in a class (a using statement maybe?)
Let's assume you want to use the ArrayList class from package java.util, either use
import java.util.ArrayList;
ArrayList myList = new ArrayList();
or use without import (say you use two different classes named ArrayList from different packages)
java.util.ArrayList myList = new java.util.ArrayList();
your.package.ArrayList mySecondList = new your.package.ArrayList();
From Wikipedia:
A Java package is a mechanism for
organizing Java classes into
namespaces
and
Java packages can be stored in
compressed files called JAR files
So for package a.b.c, you could have Java classes in the a, a.b, and a.b.c packages. Generally you group classes inside the same package when they represent related functionality. Functionally, the only difference between classes in the same package and classes in different package is that the default access level for members in Java is "package-protected", which means that other classes in the same package have access.
For a class a.b.c.MyClass, if you want to use MyClass in your project you would import a.b.c.MyClass or, less recommended, import a.b.c.* Also, for MyClass to reside in package a.b.c in the first place, you would declare it in the first line of MyClass.java: package a.b.c;.
To do this you could JAR up the whole package (including packages b and c and class MyClass) and put this JAR into your $CLASSPATH; this would make it accessible for your other source code to use (via the aforementioned import statement).
While it is not as easy to make circular dependent classes work, it may not be impossible. I did get it to work in one case. class A and class B depended on each other and wouldn't compile from scratch. but realizing that a part of class A didn't need class B, and that part was what class B needed to compile completely, I rem'd out that part of class A, not needed by class B, and the remaining part of class A was able to compile, then I was able to compile class B. I was then able to un-rem that section of class A that needed class B, and was able to compile the full class A. Both classes then functioned properly. While it is not typical, if the classes are tied together like this, it is kosher and at times possibly necessary. Just make sure you leave yourself special compile instructions for future updates.

Categories

Resources