Nobody is surprised anymore that operating systems, and distributions built on top of them, are coded in a modular way. The final product is assembled from independently developed components. This enables the coordination of work done by many people around the world, in the process assembling very complex systems in a reasonably reliable way.
A similar change can be seen to be happening to individual applications. They become increasingly complicated; they are assembled from pieces developed independently; they need to be reliable. The way to achieve and handle all that complexity is to code applications in a modular way.
Because the present applications grow in size and functionality, it is just necessary to separate them into individual pieces/components/modules/plugins. Each such separated part then becomes one element of the modular architecture. It is supposed to be independent, provide well defined interfaces that it exports (e.g. other parts can use them) and imports (e.g. those that it needs for itself to run correctly).
Splitting application into modules can greatly improve the design. It is not hard to guess that a monolithic piece of code where every line in any source code can access any other source file is much more interconnected and unreadable than a code which introduces many modules and allows such uncontrolled calls to happen just inside the module.
Modular Application vs. Object Oriented Applications are in similar position as spaghetti code vs. structured programming in the sixties. The spaghetti code used to be name of one big fortran or basic program where every line of code could use GOTO to another place in the program and this was done in quite chaotic way that at most only the writer of the program could understand. Structured programming tried to reduce the complete disorder by introducing blocks of code: for loops, while loops, if statements, procedures and calls to procedures. Indeed this improved the situation and the readability and maintainability of the application increased. If nothing else, one could be sure that a call to a method has to return once (of course except in boundary conditions).
The plain object oriented style of programming in some way resembles the situation before structured programming arived. The application is full of classes and nearly any method in class can call any other. Indeed there are public, private, protected access modifiers, but most of the granularity is done on single class level and that is too small entity to serve as a basic building brick to an application design and definitely too small to create a unit of evolution.
Modular applications in Java are usually composed of modules, where one module is a collection of classes. Some of these classes are public and thus serve as an exported API to other modules, some of them are private and cannot be accessed from outside. Moreover a module has a set of dependencies on other modules, clearly stating on a very high level what functional environment it requires to execute well. Indeed inside a module once can still apply the worsest coding practices, but still the architecture of an application can be well observed by checking the dependencies among all its modules. If one module does not have dependency on another, then it is clear its classes cannot directly access the other module's ones.
This cleans up the architecture as it prevents accidental GOTOs to completely unrelated parts of the code base. Sometimes people say that their application is too small for use of modular architecture. Well, it may be, but if it is not just student's project, then it is going to evolve and as it evolves, it is likely to grow. And rewriting a messy interconnected object oriented application to have nicer modular design is often too hard task that many people are not willing to try and rather prefer to live with old, monolithic code that is harder to maintain, but known to work. Just look at the JDK: Classes from java.lang implement interfaces from java.io, sometimes from java.util and everything is moreover wired with sun.* packages that it is nearly impossible to imagine someone to really split this into modular parts. This is just a natural result of coding in the spaghetti object oriented style.
There are just dozens of problems related to poor architecuture coding style and modular programming is one way to solve them. Modularity would give systems clearer design, control of dependencies between modules and give developers more flexibility in maintanence. Think about it when starting any new project - nevertheless big it is, do it in modular way. It is going to be big plus for the architecture of the whole application as it grows from its child days.