Various resources (infoq, jigsaw-dev, osdir) indicate that having the same package in different java modules will lead to a LayerInstantiationException, even when the packages are internal to the module (non-exported).
This seems to be the exact opposite of what the requirements say :
The Java compiler, virtual machine, and run-time system must ensure that modules that contain packages of the same name do not interfere with each other. If two distinct modules contain packages of the same name then, from the perspective of each module, all of the types and members in that package are defined only by that module.
So are (will) two modules used by an app be able to contain private packages of the same name ?
EDIT
This is an issue of JMPS as pointed by Stanislav Lukyanov
As said in the discussions you've linked, the issue is about mapping between class loaders and modules.
When you're loading two modules M1 and M2 both containing a non-exported (a.k.a. concealed) package P via a class loader CL JPMS has to reject such configuration, since otherwise both key JPMS principles - strong encapsulation and reliable configuration - could be broken. By throwing an exception here JPMS actually implements the requirement you've quoted and ensures that no conflicts may break anything later during the execution.
On the other hand, when you're loading M1 and M2 via two loaders CL1 and CL2 you're actually creating two run-time packages {CL1, P} and {CL2, P}, so there is no collision and the Layer can be instantiated.
The usability problem here is that java uses single loader for all modules of the application layer (the "starting" one, created from the command-line arguments) which leads to the LayerInstantiationException. That's currently an open issue on the JPMS list, see [here] (http://openjdk.java.net/projects/jigsaw/spec/issues/#AvoidConcealedPackageConflicts). But regardless of the issue's resolution, if needed, you should be able to deal with the split packages by writing a tiny main class that will create the Configuration you need (BTW a JPMS-aware application container will probably do it for you).
This definition is open to interpretation. It remains correct as Jigsaw ensures that two modules never define shared packages by crashing the class loading in case of such a conflict.
If you look into Java 9's class loader implementation, you can see that a package name is mapped by to a single module. Its therefore impossible two have two modules to declare ownership. It is however possible that two class loaders in child-parent relationship define the same package.
Related
In my project, I could see all the JUnit Test cases are written
in eclipse fragments not in eclipse plugin. And we do run each test classes
as JUnit plugin. I am not very much
clear about the concepts. I am relatively new to this concept.
I just googled to get better knowledge about using fragments over Plugins for Tests.
What I have understood is, fragments and host plugins share the
same class loader.Please correct me if my understanding is wrong.
However I did not understand the meaning of the below line.
If we create the tests in eclipse plugin, test classes will be loaded by a separate Classloader and will therefore not have access to the non-public methods of the classes under test.
Why it does not have access to the non-public methods? can any one help me in understanding the meaning of the above with simple example?
To understand this you need to understand how classes and classloading actually works in Java. Often we think of loading in terms of 'the classpath', but this is a massive simplification of how things work. In many Java SE envrionments this just works, but in multi-tenanted environments like OSGi it gets more complicated.
Essentially in Java classes are scoped by three things:
Name
Package
ClassLoader
It is perfectly possible to have two instances of myPackage.MyClass loaded in the JVM at more than once, you just need multiple classloaders. Even though these classes could be loaded from identical .class files they will be different at runtime. This can cause much confusion when you write code like this:
MyClass c = (MyClass)obj;
and get a ClassNotFoundException: MyClass.
Classes exist in packages and there are special visibility rules associated with this. Types, methods and fields with no stated visibility are visible to all types in the same package. When a class is loaded it gets associated with a java.lang.reflect.Package and the visibility rules are resolved by essentially checking that the classes are associated with the same java.lang.reflect.Package instance. So in the case of mypackage.MyClass if you load it twice using two different classloaders you will get two Package instances for mypackage.
OSGi is designed to support multi-tenanted class loading, this is what allows you to have two different versions of a class or package in the same JVM at once. This solve many problems caused if you have different version dependencies. It implements this by using a different Classloader for each bundle. Fragments work differently that bundles in that they are associated with a bundle and classes in them are loaded by the bundle's Classloader rather than having their own one.
To relate this back to your original question if you put your junit tests in a bundle (rather than a fragment) your class will be loaded by a different classloader, so it'll be associated with a different instance of java.lang.reflect.Package so when the JVM tests for member accessability it will fail.
The title pretty much says all.
If I provide a library and someone uses it he can write classes and add them to packages that are defined by my library. However this rises security issues as this would mean that he gets access to methods within the library that are defined without access modifier.
Is there a solution to forbid a user to add classes to an existing package?
Yes (but). The sealed manifest attribute will seal a package, preventing classes from other sources from being included. (technote)
Though it kind of depends on the context. If the someone using it gets to play with the library jar file first, then it's game over.
If both the library and client code is loaded by the same class loader, then that is in generally problematic, although classes signed with different signatures cannot coexist within the same package. If different class loaders are used even with a parent-child relationship, then at runtime packages with the same name but loaded by different class loaders are different packages.
For Java PlugIn and Java WebStart, Trusted-Library manifest entry causes the jar to be slid into a parent class loader, protecting it from potentially untrusted application code.
When trying to solve this problem, I encountered some articles, etc. referring to "isolated" ClassLoaders. I was unable to find a definition for isolated classloader via Google search, so maybe the term is not widely-known jargon, and perhaps has a different meaning in different contexts.
Anyway, Maven's surefire plugin can use an isolated ClassLoader: http://maven.apache.org/plugins/maven-surefire-plugin/examples/class-loading.html
Also one of the answers below references an article explaining how to create an "isolated" ClassLoader.
Neither reference above gives a definition for an isolated ClassLoader; they seem to assume the reader knows what that means or can look it up. However, the second link does include a hint as to what it means by "isolated":
Bootstrapping lets you run your container without polluting the system classpath. This allows you to run your deployed applications with the unpolluted system classpath as its parent. You’ve achieved classloader isolation.
But I'm not quite clear on what is isolated from what and how from this paragraph or the rest of the article. I see that he's loading one version of a class w/o overriding / overwriting another version--maybe one classloader is isolated from another by being different instances w/o one being the parent of the other? I'm not sure.
I especially covet a Google or SO search link that contains a link clearly holding the answer. A direct link to an answer works too. :)
The author is using the term "isolation" basically to mean that the bootstrap classloader for the JVM (the "main" classloader) doesn't have any extra jars/classes in it (just one simple class which in turn sets up the child classloader(s)). The article isn't real obvious as to why this is "isolated" because it only sets up one child classloader. The "isolation" term becomes more obvious when you setup more than one child classloader. These children will be isolated from each other in that they won't share any classes (other than the core JRE classes). Thus, you can do things like have each child use a different version of the same jar.
Here's how to create an isolated classloader, you'd create one any time you want an unpolluted system classpath, useful for bootstrapping Java programs.
From my understanding from the article that you linked to that an isolated class loader is a class loader that is separate to the main system class loader. That is, classes loaded by the isolated class loader won't be available to every class in JRE (only the ones that the isolated class loader loaded itself [and any classes loaded by any child class loaders]).
This could be useful because two of your dependencies might require different versions of the same library to run. That is, your dependencies might expect to see different instantiations of the same class in the library. Thus giving them two separate isolated class loaders will allow them to load the classes they require and not interfere with each other.
By default classloaders form a tree with the system classloader at the root. New child classloaders will by default ask their parent first if it can load the class, and if not, load from their own sources.
The goal of an isolated classloader is to isolate yourself from the parent classloaders by checking your own sources FIRST, then your parent SECOND, so reversing the order. This allows you to create a new classloading context where you control the first place to look. You still want to fallback to the parent chain so you can load things like the jdk etc.
You also need to take care that the isolated classloader return instances of interfaces defined in the parent classloader, or else you will run into LinkageErrors or other issues.
Here's an article I wrote in 2006, but it's still fairly relevant (it's incomplete with respect to resource loading and the apis have changed a bit over the years):
http://tech.puredanger.com/2006/11/09/classloader/
A problem: My application uses two libraries which use incompatible versions of a third library. Does someone know any method for classes isolation?
I have heard about class loaders, but I do not understand, how they could help - if we will load one version of class, we cannot load another - class is already loaded?
I also thinking about Spring, but do not know if it provides such isolation.
ClassLoaders are basically the elements that gives meaning to classes in the JVM. They form a hierarchy for wich the root lies in the JVM and loads java classes. The ApplicationClassLoader is the first ClassLoader you have to consider, as it loads all the classes of your application.
When a class is loaded, all its references to other classes are resolved and theses classes are loaded. The JVM by default provides a system where classloaders ask their parent first to see if they have already loaded a class. If not, they search in their classpath
Two classes can be isolated if they live in 2 different classloader, and not in the app classloader. It's not difficult to do. You only have to create a classloader (like URLClassLoader) while specifying its parent and its classpath(the place where the bytecode is)
then, you tell him to load a class. It will ask its parent, and if the class is not loaded yet, it will search its classpath and load it. If you create another classloader attached to the same parent, the classes loaded by the first will never be seen by the seconds as they are siblings. And the second can loads a class with the same name without any problem
That's quite a good isolation
App Servers use another form of delegation to have a frank isolation between applications. they redefine a classloader extending, for example, URLClassLoader and reverse the delegation process by starting to search for classes in their classpath first, then ask to the parent
if we will load one version of class, we cannot load another - class
is already loaded?
Not true. The class loader is considered part of the class's identity. If it's loaded by a different classloader, it's considered a different class.
If at least one of the libraries is open source, and the library they depend on is open source, no need for messing about with classloaders. Just bulk rename all the packages in one of the versions of the library being depended on, making sure to also change all code which refers to those packages. Hey presto - no name clashes. This is what Sun actually did for the JDK, when they included Xerces and Xalan behind the scenes.
getting started with osgi, i wonder what's the conceptual diffence between bundles and components. And when to use which of them. Any pointers are welcome.
EDIT:
Components and Bundles provide different interfaces and therefore they are probably not interchangeable
ComponentContext
BundleContext
A component is:
an active participant in the system
aware of and adapt to its environment
environment = services provided by other components
environment = resources, devices, ...
may provide services to other components and use services from other components
have a lifecycle
In short:
Component provide services
Bundle manage the lifecycle
A bundle can have only one activator (needing a BundleContext), and can have as many active components as you want.
That means you may end up trying to fit in one activator several loosely-related concerns into a single class.
That is why it may be easier to manage those components by Declarative Services, through the SCR (the "Service Component Runtime" which is an "extender bundle" implementing the new and improved OSGi R4.2 DS - Declarative Service - specification).
This is especially true since OSGi 4.2 because it is now much easier to write DS components as POJOs: the activate and deactivate methods are no longer required to take a ComponentContext parameter. See also Lazy Declarative Service.
Note:
It can help to replace those terms in the context of OSGi and look at "how we got there" (excellent blog post by Neil Bartlett)
Here are some relevant extracts, where the "modules" end up being the OSGi Bundles (managing Components which declare Services):
Module Separation
Our first requirement is to cleanly separate modules so that classes from one module do not have the uncontrolled ability to see and obscure classes from other modules.
In traditional Java the so-called “classpath” is an enormous list of classes, and if multiple classes happen to have the same fully-qualified name then the first will always be found and the second and all others will be ignored.
The way to prevent uncontrolled visibility and obscuring of classes is to create a class loader for each module. A class loader is able to load only the classes it knows about directly, which in our system would be the contents of a single module.
Module Access level
If we stop here then modules will be completely isolated and unable to communicate with each other. To make the system practical we need to add back in the ability to see classes in other modules, but we do it in a careful and constrained way.
At this point we input another requirement: modules would like the ability to hide some of their implementation details.
We would like to have a “module” access level, but the problem today is that the javac compiler has no idea where the module boundaries lie.
The solution we choose in our module system is to allow modules to “export” only portions of their contents. If some part of a module is non-exported then it simply cannot be seen by other modules.
When importing, we should import what we actually need to use, irrespective of where it comes from and ignoring all the things that happen to be packaged alongside it.
Granularity of Exports and Imports
OSGi chooses packages.
The contents of a Java package are intended to be somewhat coherent, but it is not too onerous to list packages as imports and exports, and it doesn’t break anything to put some packages in one module and other packages in another module.
Code that is supposed to be internal to our module can be placed in one or more non-exported packages.
Package Wiring
Now that we have a model for how modules isolate themselves and then reconnect, we can imagine building a framework that constructs concrete runtime instances of these modules. It would be responsible for installing modules and constructing class loaders that know about the contents of their respective modules.
Then it would look at the imports of newly installed modules and trying to find matching exports.
An unexpected benefit from this is we can dynamically install, update and uninstall modules. Installing a new module has no effect on those modules that are already resolved, though it may enable some previously unresolvable modules to be resolved. When uninstalling or updating, the framework knows exactly which modules are affected and it will change their state if necessary.
Versions
Our module system is looking good, but we cannot yet handle the changes that inevitably occur in modules over time. We need to support versions.
How do we do this? First, an exporter can simply state some useful information about the packages it is exporting: “this is version 1.0.0 of the API”. An importer can now import only the version that is compatible with what it expects and has been compiled/tested against, and refuse to accept
Packaging Modules and Metadata
Our module system will need a way to package the contents of a module along with metadata describing the imports and exports into a deployable unit.
So the only question is, where should we put the metadata, i.e. the lists of imports and exports, versions and so on?
As it happens OSGi was designed before 2000, so it did choose either of these solutions. Instead it looked back at the JAR File Specification, where the answer is spelled out:
META-INF/MANIFEST.MF is the standard location for arbitrary application-specific metadata.
Late Binding
The final piece of modularity puzzle is late binding of implementations to interfaces. I would argue that it is a crucial feature of modularity, even though some module systems ignore it entirely, or at least consider it out of scope.
We should look for a decentralised approach.
Rather than being told what to do by the God Class, let us suppose that each module can simply create objects and publish them somewhere that the other modules can find them. We call these published objects “services”, and the place where they are published the “service registry”.
The most important information about a service is the interface (or interfaces) that it implements, so we can use that as the primary registration key.
Now a module needing to find instances of a particular interface can simply query the registry and find out what services are available at that time. The registry itself is still a central component existing outside of any module, but it is not “God”… rather, it is like a shared whiteboard.
In OSGi terminology a "component" is like a run-time service. Each component has an implementation class, and can optionally implement a public interface, effectively providing this "service". This aspect of OSGi is sometimes likened to a service registry pattern.
Components in OSGi are, by definition, provided by a bundle. A bundle may contain/provide multiple components. While by itself a bundle may not provide a service, components/declarative services are used to make OSGi more service oriented. You are under no obligation to use components/services.