I have a java package foo.bar. It contains few classes, that are frequently modified, improved etc in this time of project.
I don't want any developer to use classes from the other packages in this one. I want this package to be separated in its usage. So this package must be isolated.
I could make an external jar, but that would introduce much more handling for little number of classes, that it does not make sense.
I want this inspection to be run from my build process.
I tried several code-inspection tools (pmd...) but I was not able to configure this. How to do this?
Related
Is there a way to automatically find out which Java classes are actually loaded (either during compile time, as far as that's possible, or during the runtime of an application), and to throw out all other classes from a JAR to create a smaller JAR? Does that actually make sense in practice?
I am talking about the application classes for an application JAR. Usually there are lots of libraries in an application, and an application rarely needs all features of those libraries. So I suspect that would make a considerably smaller application. In theory that might be done for example via an Java agent that logs which classes and resources are read by one or several runs of an application (or even just by java -verbose:class), and a maven plugin that throws out all other classes from a jar-with-dependencies. Is there already something like that?
Clarification: I am not talking about unused dependencies (JARs that are not used at all), but about removing unused parts of each included JAR.
Well, the Maven Shade Plugin has an option minimizeJar when creating an Uber-JAR for your application:
https://maven.apache.org/plugins/maven-shade-plugin/
But, as others already pointed out, this is quite dangerous, as it regularly fails to detect class accesses which are done via Reflection or other dynamic references.
It may not be a good approach automate, as application can use reflection to initialise objects or one JAR is dependent on another JAR.
Only way that I can think of is to remove each JARs one by one and check if application runs as expected. Then again in this approach all modules of the application has to be tested, since one module can work without particular dependency and other may not.
Better solution is to take care while developing. The application developer must be careful in adding a dependency and removing unwanted dependency after his/her piece of code is done.
Global strategy.
1) Find all the classes that are loaded during runtime.
2) List of all the classes available in the classpath.
3) Reduce your class path by creating copies of jars containing only classes you need.
I have done 1 and 2 part so I can help you.
1) Find out all the classes that are loaded. You need 100 % code coverage (I am not talking about tests, but production). So run all possible scenarios, so all the classes your app needs will be loaded and logged.
To log loaded classes try several approaches. Reflection, –verbose:class flag, also you can learn about java agent. It allows to modify methods during runtime. This is an example of some java agent code or another java agent example
2) To find all the classes available in jar, you can write a program. You need to know all places where application jars are placed. Loop throw these jars (You can use ZipFile), loop through ZipFileEntry entries, and collect all classes.
3) After that write a script or program that reassembles your application. For example, now you can create a new jar file for each library and put there only needed classes.
Also you may use a tool (again, you are a programmer, so write a program), which checks code for classes dependence. You do not want to remove classes if they are used for compilation. When I was a student, I wrote code alanyzer, which builds an oriented graph for classes dependencies.
As #Gokul Nath KP notes, I did this before. I manually change gradle and maven dependencies, removing one by one, and then full regression test. It took me a week (our application was small comparing to modern world enterprise systems created by hundreds of developers).
So, be creative, and in case of success, your project will be used by millions!
I have a game written in Java and a whish to write a generic ModLoader/AddonLoader application. A separate application/api that would allow you to create mods/addons for my projects that add extra implementation that I do not want in the main application.
However I am not sure how to go about this, i've done some research and im not too sure how to make the mod/addon interact with a loader which interacts with the main application to add new features/modify old
Many Thanks
Elliott
Since you're looking for some basic guidance I'll suggest the following:
You need a way to pull in classes after the core application is running. That means you will need these classes on the classpath. The simplest way to do that is probably to have your classpath include a folder like "addons" so that all the jars in that folder are automatically on your application's classpath.
Once you have your classpath set up you will need to somehow make use of the appropriate class(es). This part is hard to speak generically about because it depends heavily on how you intend your addons to work. Some tools use annotations to help with this and you can probably look at some open source projects for examples. One that comes to mind is Maven, it makes use of annotations in its plugin system. The general concept is that you need to decide how many different kinds of addons you have and how you will identify them and make use of them.
Typically making use of an addon involves instantiating that addon which is why it can be tricky. Some plugin systems require that addons be written such that they use a specific package name. They do this so that they can make use of reflection to find all classes in a given package and then process them.
Hope that helps to get you started!
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/
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.
When my project grows too big, it also get harder to recognize the growing number of classes. I'm looking for a plugin for eclipse, that makes it easier to differentiate the classes by assigning icons or colors to them.
Alternatively I'm looking for any tools, plugins or advice to see through the jumble of classes.
(Currently I'm only using packages for grouping classes)
You should be using packages to the full extent. That means, whenever you find that at least 2 classes in an already existing package share a common aspect, think about moving them into yet another sub package.
Over time, this can lead to quite long package names like org.eclipse.product.addon.technology.ui.someview.listeners. As those are not easy to browse, use the compressed package name display of Eclipse, which allows you to replace any package path by an arbitrary string (only for display in the package explorer). So your very long package names get shortened like here: