Recently, new Java module system has been a great deal of attention. After I watched Devoxx section on Jigsaw demo, I was excited, I feel it should be the solution for the complex version of the problem classpath and JAR traps and other issues. Developers can use their final desired any version of Xalan, without being forced to use the licensing mechanism. Unfortunately, leading to more effective modular system of the journey is not very clear.
Before studies do, we first look at some basic concepts:
Modularity is a very important tool for solving complex problems. The application is divided into different parts (modules, libraries, packages, subprojects, and components), and then were calculated, it is an effective way. Modular ultimate goal is to define a set of API to communicate between modules used.
If all inter-module communication is only achieved through this API, then the module is loosely coupled, then:
change the implementation of a module can easily
the development and testing of each module can be easily open to independent
object-oriented model is also a similar reason. In OOP, the ideal situation is to have a large number of small, reusable, simple and good separation of the object. In a modular system, you can achieve the perfect small, reusable, simple and good separation of the modules. Their initial ideas and motivation are exactly the same, but the scale is different.
Traditionally, Java there are two ways to achieve modularity. Logical separation is the most natural way. It includes dividing an application into logical modules (sub), and finally deployed as a complete application. By defining the right package to achieve logical separation it is possible, but a more general approach is to split the application into some of the archive file (that is, JAR packages). Logical separation can promote reuse in modules, will enable the loose coupling between modules. You may even have a defined API, and then announced that all communication between modules should be given through this API to achieve. This idea has a big problem, it is hard for you to break the strong we are using this restrictive usage, and without any kind of mechanism to ensure that the API usage. You also can not type those applications through a given module to use and as part of a public API class area separate. If a class is "public", and that it can be any other classes, either call it belongs to that class module. On the other hand, the visibility of the protected class or package level calls in its internal module is also limited. Generally speaking, it covers some of the packages and package type modules need to be able to call each other. Therefore, even if an application is some logic modules, but if these modules are coupled, the separation also simply useless.
Another traditional way is physical separation. You can split the application into different components, each component and then deploy to a different JVM and to achieve separation. Communication between these components, such as RMI, CORBA or WebServices via remote access mechanism. Physical separation to achieve the separation, but also to achieve a loosely coupled, but the negative effects are spending big. To achieve separation using specialized remote access mechanism, a little overkill taste. This will increase the development and deployment of unnecessary complexity, the performance will be affected can not be ignored.
modular system located between the logical and physical separation of separation. It emphasizes the separation module, but each module can still be deployed to the same JVM, and communication between modules by simple composition of the traditional method calls, so there is no expenditure burden runtime. In the Java ecosystem is the most popular modules framework OSGi. It is a mature specification, with several different implementations. In OSGi, the module is called a bundle, each bundle is equivalent to a JAR. Each bundle also contains a META-INF / MANIFEST.MF file, which will announce which export package (package), and import which packages. Only those exported classes in the package in order to be used by other bundle, while other packages only packet-oriented internal members, the bag can only be used in a class of its own bundle.
For example, the following statement:
This specification specifies the name of demo-spring-osgi-dao of the bundle, which you want to import the package name net.krecan.spring.osgi.common in the class, and export the package named net.krecan.spring.osgi.dao in class. In other words, this statement indicates that other modules can only be used net.krecan.spring.osgi.dao package. Conversely, this module is to be used only net.krecan.spring.osgi.common package, but may also be responsible for providing specialized modules export this package provided by OSGi. Of course, you can define multiple package names in the import and export declarations.
require special attention, OSGi's modularity is built on top of Java. It is not part of the language! Here, although the separation module may be performed by GUI, but can not be performed by the compiler. When running OSGi-based application, you will need an OSGi container. This container may be part of the runtime environment, such as in Spring DM server, or it may be embedded in the application. This container is not only responsible for providing separation, also provides other, such as security, management and life-cycle management modules such services. OSGi also provides a number of other interesting features, but these are not of concern to this article.
About JSR-277 was a lot of controversy, the JSR was some repetition with OSGi. For several months, experts from both sides are strongly debated who better until JSR-277 has been declared abandoned and the new modular system will be part of Java 7.
The first part of this new module system is JSR-294, the so-called super package. It also explains the concept of this specification module part of the Java language.
JSR-294 introduces a new visibility keyword "module". If a member has such visibility, it means that only members of the same module can be seen. It will create an internal API, only the module itself can be called. In this opinion, "public" keyword should be declared only when using a common API. While in other cases, you should use "module" or more keyword visibility restrictions. Of course, once the language has "module" keyword, visibility restrictions between the module will be responsible for checking by the compiler.
JSR-294 also allows the definition of dependent. You can in a given version, the definition of a module depends on another module. For example:
@Version ( "7.0")
@ImportModule (name = "java.se.core", version = "1.7 +")
The last sentence shows that "org.netbeans.core" module dependency "java.se.core" version 1.7 or higher. This is similar to Maven's dependency or OSGi import. You can also temporarily forget about these syntax, because syntax may be another change in the future. Importantly, here the dependence is defined in the module-info.java, it will be compiled into class files. The OSGi, the dependence is defined in plain text file.
Jigsaw project is the second part of this new module system. I expect it will be JSR-294 specific to Sun's implementation, will be modular Sun JDK implementation. Now create a complete modular JDK is necessary, Sun will hope the standard library distributed into modules. This simplifies the direct integration of the contents of the JRE. Swing the entire JRE In addition to all of the content and therefore can run on mobile devices. It is also possible to introduce a new standard for the language API, without having to wait for the release of a new version of the entire platform. Now, it seems, this project definitely hope to achieve.
But I am also a concern, that is, the relationship between proprietary Jigsaw and the JSR standards are not between clear, as Mark Reinhold said:
for Jigsaw investment will undoubtedly create a simple, low-level module system, it is designed strictly modular JDK towards development goals. Developers can use this modular system to their code, Sun on the module system will absolutely support, but it will not be an official part of the Java SE 7 Platform Specification, or may not be realized other SE 7 supported.
These words are not very clear, there were a lot of questions. He means that the module can only be created in the Sun JRE run? Or say that if developers wrote "@ImportModule (name =" java.se.core ", version =" 1.7+ ")", then this module can only be run in the Sun JRE, but can not run in IBM JRE environment? or he meant not to say that Sun will be in some way the JRE it split into many modules, Oracle will choose another way to go split it (Translator's Note: At least for now, do not have such a possibility, because Oracle has just acquired the Sun)?. We hope not, because there are principles of "write once, run anywhere".
careful study the issue more. It is not clear what Jigsaw main objective of the project Yes. The main objective of the project itself, according to the announcement of view, it is to be achieved by modular Sun JRE, but if purely to achieve a modular, then it does not need to make any changes to the language. Sun JRE can be modular, rather than amend the Java language itself.
These changes in language will become the Sun JRE modular by-product of? If it is, it completely wrong! Language change must be first-class citizens, not the exclusive products.
My other concern is that dependence. If the dependence by the module system to manage, it is no longer a need classpath. On the one hand this is good, because classpath often will lead to so-called JAR hell issues. On the other hand, classpath is an extremely flexible, I am afraid that this flexibility is not possible for a static module dependency can have. Let's look at why:
When you deploy dependent
There are two in the Java classpath (classpath). Is to build a path (buildpath), it is used in build. Another class path is used at run time. Both are almost the same, but not quite. The classic example is the JDBC driver. When building, you do not need to specify the JDBC driver, JDBC interface is part of the core Java libraries. But at run time, it is necessary to make sure that you have a class path of JDBC driver. If a programmer needs to modify the database connection, he only need to modify the class name of the drive in the configuration file, and add the driver jar files to the classpath it. If all dependencies need to specify at compile time, the developers obviously could not do that. Of course, Java EE, and he can use JNDI data sources, but nothing like in Java SE, once the modification JDBC driver, you have to recompile the entire application, which is obviously very tricky.
In general, recompile unlikely. In some organizations, the final application is assembled from a so-called application modules from the assembler. Developers do not have the source code, he just put together some of the JAR, modify the configuration file, and then create the final package. Application assembler role even in Java EE specification have mentioned.
similar question is optional dependent. We assume that we have to do a log4j logging framework like this. This library can log on JMS, JMS package therefore must be covered in the build path. But 99% of users do not use JMS log, so they do not need to rely on your classpath. For such problems, there must be some mechanism to resolve. We need to build a library of this module, the dependence on the end user is optional. Of course, the situation is perfect, JMS feature is an independent module, but we do not live in a perfect world, and sometimes in this way to split the project is not realistic.
Another big problem is the dependency conflict. If you've used Maven, not difficult to understand what I'm saying. Most enterprise applications will be used in about a dozen third-party libraries, interdependence between them is sometimes a conflict occurs. For example, a developer wants to use Hibernate, it depends on commons-collections 2.1.1, he would like to use commons-dbcp, we need to rely on commons-collections 2.1. Application developers themselves or assembly needs to decide how to solve such problems. Either he decided to use only with a specific version of the library, or the decision in the application of different parts with different versions of the library. Importantly, these problems can not be resolved. It is always a need for people to understand the various modules in the application how it works to make a decision, and this people have to be able to identify possible incompatibilities between different versions.
dependent on Java, there are many things this article does not discuss, but need to bear in mind is that they are not static. Member of an application may use a certain set of class libraries, and it's running it takes a completely different set of additional libraries. All modules system must somehow solve these problems out. Maven has a number of options on how to configure dependencies and how to deal with conflict, and so dependent, but it is just a build system. The worst case is the need to manually configure the classpath. OSGi is a different situation. It only deals with the runtime (deployment) dependent, regardless of when to build. The new Java module system will also support the build-time and run-dependent (I guess), and even the existing complex issues will become more complex.
Of course, I believe Sun's engineers did not want to undermine Java itself. I think they also to make Java better, easier to use, but I am worried that political and market factors much larger than the impact of technology. Again, this is not just a change in the API or the Sun-specific changes. This is the language-level changes! Once the language is changed, once you add a "module" keyword, there will be no going back. Until then, Java there will be a modular system, whether like it or not, we all have to use this module to the system. Really hard to imagine with modular JVM, the Java language is difficult to imagine there will be a "module" keyword, and on top of this we have to use OSGi.