Using Java's default package in Eclipse - java

In Eclipse, when I start a new Project, I go through the wizard, and when I get to writing my first class for that project I am asked to select a package. Sometimes out of laziness I just choose the default package.
The wizard warns me this is discouraged. Even if I ignore the warnings I never have any problems with the application due to this. Or at least, so far I have never had any problem.
So why does Eclipse want me to create a new package?

Eclipse, and most other IDEs, are geared towards large projects. Hobbyist programming and small-scale assignments can get by in IDEs often, but be aware that the general assumption would be for larger projects - anything between 10 and 5,000+ classes.
There is also a chance that you create a class which has a similar name to something in the Java API - for example:
java.rmi.MarshalException and
javax.xml.bind.MarshalException
Ambiguity in instantiating the class (throw new MarshalException();) if both classes exist on the same classpath is a compilation error.

You actually can't import classes from the default package. I understand it's allowed as a convenience or for very small (one class file) tasks.

Related

Is there a smart way to manage the imports in Java when import path includes version number that changes frequently?

Context:
We have Java application on Maven and Spring framework.
We are using a third party library in our project where classes from the library have to be imported this way(for example):
import com.doodle.api.v201709.Class1;
As a result,whenever there is a version change , it is not only the pom.xml has to be changed but almost all of the classes has to be updated to change the version from v201709 to v201711 for example.
I tried to handle this issue by putting all of these kinds of imports in one class and extending that class in those classes where these imports are required. Seems classes where the imports are required are not getting them and I am seeing compilation failure with "cannot find symbol" error msg.
Any idea on how to handle this issue?
Half an answer:
I tried to handle this issue by putting all of these kinds of imports in one class and extending that class in those classes where these imports are required.
Translates to: you don't know what import statements are and how they are used.
Meaning: import statements are not something that you can pass down using inheritance. They are a purely syntactical thing for human programmers. You import a class such as x.y.Z ... so that you can use Z within your source code, instead of writing x.y.Z all the time.
The compiled byte code knows nothing about imports - they are gone. Instead, the compiled byte code uses x.y.Z all the time.
Therefore your idea to "import" names, and using inheritance to sneak the imports into other places, as said: does not work.
And in that sense the real answer is: you have to look into proper tooling that makes it easy to change such things. You probably find such refactoring capabilities within IntelliJ or eclipse. Or, alternatively, you turn to sed/awk and command line magic (it shouldn't be to hard to search for import x.y.v1.Z patterns to replace them with import x.y.v2.Z.
Java doesn't give you that flexibility at compile time.
Among alternative options that you have:
Properly version your code, that of your dependency, then use a build dependency management tool such as Maven. This is safer as it allows version control and possibility to revert to the previous version if the new one doesn't work. This option reduces coupling between the two code bases.
Use scripting: With something like Groovy, you can take advantage of AST transformations and add dynamic imports at runtime.
I ended up creating a class with all the imports and then imported that class wherever required.

Package for standalone program [duplicate]

This question already has answers here:
Is the use of Java's default package a bad practice?
(3 answers)
Closed 6 years ago.
I'm pretty new to Java, and I know what packages do. You use them to sort multiple files of a Java application together. However, is it standard to put it in a package if your application only has a single class? What are the pros and cons of doing this?
EDIT: I'm packaging this single class into a .jar file after.
From oracle documentation, it is clear that
The primary motivation for jar development was so that Java applets
and their requisite components (.class files, images and sounds) can
be downloaded to a browser in a single HTTP transaction, rather than
opening a new connection for each piece. This greatly improves the
speed with which an applet can be loaded onto a web page and begin
functioning. The JAR format also supports compression, which reduces
the size of the file and improves download time still further.
Additionally, individual entries in a JAR file may be digitally signed
by the applet author to authenticate their origin.
From Package Documentation of Oracle,
For small programs and casual development, a package can be unnamed
(ยง7.4.2) or have a simple name, but if code is to be widely
distributed, unique package names should be chosen using qualified
names. This can prevent the conflicts that would otherwise occur if
two development groups happened to pick the same package name and
these packages were later to be used in a single program.
It really depends on how you're compiling and running the program, but ultimately it's your choice.
Let's have a look at some of the different ways you might build your program.
1. Compiling the file with javac
If you're compiling the file using javac then the package will not matter. It will generate the .class file the same directory as the source file.
2. Compiling to a JAR File
If you're compiling to a JAR File, then the .class file will be inside the directories specified in your package name. Although this would not affect how the program is ran.
In both of these cases, I'd say that the package identifier is unnecessary for a single-file program. However, there is an exception.
The exception...
If ever you plan to use the class in a larger program, then adding a relevant package name would be essential.
This is because it would...
Prevent name collisions when other classes in the default packages have the same name.
Help people know whether or not your class is the one they want.
Can you imagine if 20 different developers made a List class in the default package, and somehow they all ended up in a project? It would be chaos! How would I choose the right List?
So in the case of writing a class that others will use in their own projects, you should definitely use package names.
It is probably non-production application if it has a single class and doesn't have any dependencies or resource files. So it is completely up to you how you will start your app.
If you want to distribute your app - make it in compliance with the standards, put it in a jar, publish to maven...
Java classloaders identify your classes by concatenating the package and the class name. So, if you don't use packages, the probabilities of name collisions are higher. Even though your app consists of only one class, you're going to reference many others, explicitly or not.
Also consider that you'll only be able to build very trivial applications with only one class, so probably that condition won't last forever.
Besides that, a class without package is a border case, so you'll probably find many tools that don't work with it.(I had this problem with the Web Service builder tool for Eclipse).
In short, use a package. It won't cause you any trouble, and (at least potentially) will save you many.

Strategy to separate module from Java project

I'm separating a module from a Java project (essentially creating a separate Java Project for the module). I've been spending a lot of time to figure out the class dependencies. What strategy/tool can I use to help speed up the process?
For example, if I know for sure that I need to extract out class A into the new project, how would I quickly identify all the classes on which class A depends for successful compilation.
Approaches tried:
At the moment, I'm going by repetitive cycles of: add required classes to new project -> compile -> gather necessary classes from original project based on compiler error message -> repeat.
Generating UML Class Diagrams is not working out as most UML reverse-engineering tools seem to have some limitation or the other when it comes to identifying inheritance, associations, etc. I already tried ArgoUML.
It looks like you need "Dependency viewer" of Intellij IDEA.
It can be found under Analyze > Analalyse Dependecies...
In my experience, Eclipse has the best built-in utilities to get information about class dependencies and such. You could go into the debug view and trace each class and/or method.

Why shouldn't we use the (default)src package?

I recently started using Eclipse IDE and have read at a number of places that one shouldn't use the default(src) package and create new packages.
I just wanted to know the reason behind 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.
Originally, it was intended as a means to ensure there were no clashes between different pieces of Java code.
Because Java was meant to be run anywhere, and over the net (meaning it might pick up bits from Sun, IBM or even Joe Bloggs and the Dodgy Software Company Pty Ltd), the fact that I owned paxdiablo.com (I don't actually but let's pretend I do for the sake of this answer) meant that it would be safe to call all my code com.paxdiablo.blah.blah.blah and that wouldn't interfere with anyone else, unless they were mentally deficient in some way and used my namespace :-)
From chapter 7, "Packages", of the Java Language Spec:
Programs are organized as sets of packages. Each package has its own set of names for types, which helps to prevent name conflicts.
I actually usually start by using the default package and only move it into a real package (something fairly easy to do with the Eclipse IDE) if it survives long enough to be released to the wild.
Java uses the package as a way to differentiate between classes. By using packages, you can have an org.example.Something class and an org.example.extended.Something class and be able to differentiate between them even though they are both named Something. Since their packages are different, you can use them both in the same project.
By declaring a package you define your own namespace (for classes). This way if you have two identical classes using a different package name (namespace) will differentiate between which one you want to use.
The main reasons I can think of are:
It keeps things organised, which will help you (and others!) know where to look for classes/functionality.
You can define classes with the same name if they are in different packages.
Classes/etc in the default package cannot be imported into named packages. This means that in order to use your classes, other people will have to put all their classes in the default package too. This exacerbates the problems which reasons 1 & 2 solve.
From a java point of view, there are two general dev/deploy lifecycles you can folllow, either using ant to build and deploy, or the maven lifecycle. Both of these lifecycles look for source code and resources in local directories, and in the case of maven, in defined repositories, either locally or on the net.
The point is, when you set up a project, for development and eventually deployment, you want to build a project structure that is portable, and not dependent on the IDE, ie. your project can be built and deployed using either of your build environments. If you use a heavy dependence on the Eclipse framework for providing class variables, compile paths, etc.. you may run into the problem that your project will only build and deploy using that configurationj, and it may not be portable to another developers environment, so to speak.

Organize small utilities functions

After years of programming, we all have a set of small functions used as helpers utilities that we wish it comes build-in so we can use it in any project and have ti taken care by more people (test and optimized).
I have quite a collection of these functions. I wonder how do you guys organize them? Do you have any tips?
This is how I do it. I put it in a separate project (an eclipse project) let say "MyUtils" and it referred to by other projects. This works but because the utils collection are getting bigger and bigger something it is kind of weird that the utils are bigger than the project code (for small projects). And to ship it in Jar, you have to select them all by hand (or include them all). Is there a better way?
Also, as Java requires all functions to be in a class so I have ton of static functions (those that does not fit in OOP) for example a function read text file from a file name. Like this:
package nawaman.myutil;
public class UText {
static public String ReadTextFile(String pFileName) {
...
}
static public String[] ReadLines_fromFile(String pFileName) {
...
}
static public String ReadLine_fromFile(String pFileName, int pLineNumber) {
...
}
...
}
So when I need to include all the functions goes when though it is not used.
Is there a better way to do this?
I use eclipse on Linux anyway if there is special technique for it but fell free to share if you have techniques with other tools.
I treat such utility classes just like other components external to the software that I develop:
For each component I create a Eclipse project and build it to a jar.
Classes are grouped logically in packages, e.g. [domain].util.net, [domain].util.text etc.
In a project I include the dependencies I need. Maven can help you here.
You write that utility classes have a lot of static methods. That's something I don't use a lot. For example the text functions you show can be refactored to a class or set of classes that extend or implement classes and interfaces from the collections framework. That makes it easier to integrate my code with other libraries.
This works but because the utils collection are getting bigger and bigger something it is kind of weird that the utils are bigger than the project code (for small projects). And to ship it in Jar, you have to select them all by hand (or include them all). Is there a better way?
For my projects I use javac to select all the classes from my util libraries. For this I compile all classes from my project to an empty output directory. javac automatically resolves the dependencies to the util libraries because I added the util library pathes as source pathes. Now I can create a jar that contains all classes of my project and only the needed classes of the util libraries.
Also, as Java requires all functions to be in a class so I have ton of static functions (those that does not fit in OOP) for example a function read text file from a file name.
I do it the same way. But I try have a lot of small util classes instead of a few big ones, so that I don't have to include tons of unneeded methods to my jars.
My "utilities" have their own package namespace and SVN repository. They are, in essence my own libraries: distinct projects which may be pulled in, shared, tagged, updated, whatever.
The organization used within each of these "libraries" depends on the scope and function in question.
Because I disagree with the structure being a slave to some potential class/JAR output:
If you are concerned about "method bloat" in the classes and/or JARs, please use an automated tool to combat this. ProGuards is just one example and, while it can obfuscate, it can work equally well at just "dead code elimination".
Split your utils module into smaller subprojects. Use Maven or other build system to track versions of all your util modules. They are crucial to your systems because I think they used are in almost all your projects. Use tools like Findbugs or PMD to mesure quality of your code.
Every project need to know which version of utils module is using. It unacceptable in my opinion to add to binaries/sources of one of yours 'nonutils' project some loosely coupled util classes.
Please, revise yours classes with other commons projects like Apache Commons. I assume that lot of your utility code is similiar. Think better of rewriting yours static metods, because they obstruct testing (I'm sure that Findbugs will be complaining a lot too).
To sum up - creating a utils library is a hard stuff and a lot of responsability. So requirements in area of code quality are very high. I hope that my advice will help.
You should be very careful with removing classes after compilation - you may end up in a class not found situation at runtime. If you never use reflection or Class.forName() you should be safe, but those introduce runtime dependencies which the compiler cannot help you with (like it can with "new").
Remember - those classes not used do not use memory in the running program, only uses bytes on disk.
Personally I've ended up at saying disk space is cheap, and the risk of accidntially removing a class defintion used causing a runtime break, is not worth it to me, so I say - all code used for compilation must be shipped.
I don't use Eclipse, but in Visual Studio you can add a reference to file without it being physically moved or copied. This allows you to define a file in the root of your source control that all of your projects can reference without it being included in every project or having to deal with the copying problem. With this kind of solution you can intelligently split your util methods into different files and selectively include them based on what individual projects need. Also you can get rid of the extra .jar.
That said, I have no idea if Eclipse supports this kind of file referencing, but it might be worthwhile to look.

Categories