Dependent Classes in Java - java

For our assignment we need to write code for a neural network. The way I planned to do it was to write a Node class, which is a node within the network; a Layer class, which is a layer of nodes and a NeuralNet class, which is a network of layers.
I'm having a lot of trouble understanding the way Java is designed to work for imports. To me it seems that it should be a simple matter to include my Node class in my Layer class, and my Layer class in my NeuralNet class, however Java doesn't like importing from the default package.
What I have read suggests that anything you import needs to be in a package and packages have their own subdirectory. Because of the way I plan to structure my classes, this leaves me with what seems to me, an unwieldy and unnecessarily complex directory structure ie.
neuralpkg.layerpkg.nodepkg.Node
Can someone explain to me whether this is the only way to implement the structure that I want or whether there is some much, much simpler way that I've missed?
For what its worth I'd have no trouble writing this in C/C++, but attempting to import in a similar style has only given me heartache.

You don't need to layer the package like neuralpkg.layerpkg.nodepkg, where "neural", "layer", and "node" are subpackages for the respective classes.
You can simply create a package named "ben" and put all of your classes in there. So within your source directory you'd have a layout like:
--/ben
----Layer.java
----NeuralNetwork.java
----Node.java
Each class definition should then start with the line package ben;.
Classes in the same package don't need to import each other.

It's more like this:
Make a directory called src. This is the root under which all java files will go. Underneath it, make a series of directories called
com->ben->neural or some such. Put all your java source files in the neural folder.
Also, what IDE are you using? Score yourself Netbeans, Eclipse, or the free version of IntelliJ. Java needs a good IDE. When you create a new class, the IDE will do the package statement for you and help immensely with the imports.

Think of packages in Java like namespaces in C++. From what it sounds, it seems like you want everything in the same namespace. The default package can sort of be thought of as unnamed namespaces (I think).
What you should do is just create a simple package com.class.hw01 for example. And put all your classes in there. That way you don't even have to import anything, you can just declare/use your classes just like in C++ if they were in the same namespace.

Related

What is basic package structure in the project for Java?

I'm trying to learn some basics of Java and Spring. Recently I came across some beginner project and one of the first steps was to create a Spring Initializr thanks to its website, where everything is clear to me. The next step was to create a basic package structure in the project: model, controller, repository, config, service.
Could someone explain me what exactly is meant by creating these packages after creating a new project? I tried to look up the information myself, but unfortunately I couldn't find an answer anywhere.
I will start by recommending reading about Packages in Java.
In a nutshell, packages are folders. They are used for storing (mainly) classes, but other entities can be stored in packages as well. For example, text files, pictures, etc. In Java, there is no hard set rule that state that only classes must be stored in packages. That said, this is typically not the way projects are structured.
One of the most important functions of packages is to provide namespace for classes. Consider two classes named Table. One is a table containing data and the other is a table used to put stuff on top of; for example a dining table. This means that Table will have to different meanings. Operating Systems will not allow for two files with the same name to exist in the same folder. Therefore, you need to put them in two folders (packages). In the code, you can break ambiguity by declaring the objects using the class' fully-qualified name. For example,
myproject.furniture.Table diningTable = new myproject.furniture.Table();
myproject.data.Table dataTable = new myproject.data.Table dataTable();
There is also access protection with packages by using default access modifier (no modifier). For example:
package myproject
class PackagePrivateClass {
// class contents omitted
}
Notice that this class is not public. In Java, this means that this class is visible to other classes in the same package only. Not even classes in sub-packages will have access.
In summary, packages provide namespace, physical organization, and access protection.
The second thing you should be familiarized with is the best practices with regards to naming your packages. Organizations tend to have packages structured with the domain first, then the main system the code is part of, then subsystems, etc. Before providing examples, here is an article about Package Naming from Oracle.
java.awt => Contains all of the classes for creating user interfaces and for painting graphics and images. AWT stands for Abstract Window Toolkit
When you see the package name, it gives developers and idea what type of classes can be found inside. This will help looking for functions when you are not familiarized with the API (which in turn will help you learning the API much faster). Imagine how hard would be to learn Java if all classes were in the same folder. Imagine how hard will be to figure out what the project does if meaningful names are not used. In the example above, it is kind of easy to figure how what to expect out of classes in the java.awt package.
I was hoping to give you more examples, but I am out of time. Maybe later I will return and write more about this.
Package is nothing but a group of classes. You want to categorize your classes basis their respective purposes. If it's just for self-learning, your package structure should be like
org.novak.sample.service.*
This package should contain all Services, not anything else.

Stop external library access to runnable Jar

So I have a Java application I will be releasing to one of my communities for a price. The app is just about complete and ready to be obfuscated but the problem is;
I found that when I add the Jar to another project in Eclipse you can instantiate classes externally and use my program as an external library to make scripts outside of my program. This is not what I'm wanting to achieve here... I'm self taught so I have grey areas of knowledge as I haven't learned formally, but I'm pretty experienced in Java still... I've tried googling it and nothings coming up, maybe I'm not phrasing it correctly. But if I could get some help it would be appreciated.
Here is my structure of my packages:
src.com
Contains main class
src.com.scripts
Contains Abstract Script class
src.com.scripts.impl
Contains the actual scripts that extend the abstract Script class
What I've tried doing:
I removed the public Identifier from the Abstract Script class but then it isn't visible to the main class to call it from as it is in the package before. So how can I go about this when my project is sorted in packages and they all need to access eachother?
There is no solution.
If people want to reverse engineer your code, they will. There is nothing you can do to change that. public/private are essentially meaningless beyond helping you write good portable code.
That being said, Java is generally much easier to reverse engineer and make bindings to than other languages. Java doesn't inline functions and unless told otherwise, it will even leave all of your class and method names intact. If you had used a language like C, the optimized binary would be a bigger pain to work with, but the result would still be the same.
Just obfuscate the jar and call it a day. Manually changing how you write your code is more harmful to you than it is to them.

Any way to organize classes within same package

I'm writing a Java library that has a simple interface, but a lot going on behind the scenes. In order to keep the API surface small, I've kept the library as one large package (so that I can make most classes package protected). Now that the library has grown, it's become a little difficult to find the class you're looking for.
Is there any way to visually organize a lot of classes in the same package?
I know that in general, creating a new directory also creates a new package. Is there any way around that? Is it at all possible to have multiple directories that are all in the same package?
If not, I'm also open to any creative ways to visually organize the classes (I've considered prepending class names with the "package" it would be in, but I don't think that helps much).
If there are any solutions involving some sort of IDE tags, that would be acceptable too (we use IntelliJ).
Thanks!

How to import duplicate package structures and classes in a Java application

I am wondering if there is a way around this problem without changing the package structures.
I have 2 similar web apps with identical package structures. Classes are the named the same as well.
I would like to use both versions of these packages and create objects from the classes in a third app.
The reason for this and as an example, is that I want to create a single web app that manages user accounts for these 2 other web apps. The package structure for both is com/mycompany/User.java
The problem (as I see it) is that I can't just have these 2 apps package structures in my classpath and have a way to differentiate between them when creating objects.
i.e.
When creating a User object, how can I specify that I want to create it from package 1 or package 2. I don't want to refactor the code or change the way the apps packages are structured.
you can't do this, in java a class its identified by his package and his name, you cannot have two classes in the same package with the same name.
In fact its really a very bad practice, why you have two things with exact the same name representing two different things?. Change your package an include the application name, at least, in the name:
com/mycompany/myapplication/User.java
You could possibly use 2 classloaders loading from different .jar files (for a sophisticated solution check out OSGi). But it's going to be very confusing, and I would recommend renaming/repackaging.
You cannot do that in any recommended way.
You should refactor it.
If there is no chance of refactoing, e.g for legal reasons, then try this approach:
Although I will not recommend it, you could use Proguard to obfuscate only the class User, and use a predefined obfuscation.map and name it there User2.
The output is a new jar file, where the class User has a new name.
Example of such an obfuscation.map entry:
com.company.transform.TransformException -> ad.d:

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.

Categories