About Classloading Isolation | MuleSoft Documentation
# About Classloading Isolation
The Mule 4 classloading schema isolates the runtime, apps and modules from each other. Each specifies the packages (rather than the classes) to export as part of its API, making those specific packages visible.
Mule 3 classloading issues:
  * Modules were not isolated from each other.
  * Modules were not isolated from the Mule runtime.
  * Modules were not isolated from Mule apps.


In Mule 3, modules that used some library could conflict with other modules, apps, or runtimes that used another version of the same library. This conflict led to classloading problems with confusing error messages like `ClassNotFoundException` or `NoSuchMethodException` that were hard to troubleshoot.
## Modules Classloading Isolation
Classloading is automatically filtered by package and not by class, meaning that modules need to specify which packages to export and make visible to the Mule app.
To determine what packages to export, the SDK introspects each configuration, connection, and component return and input types to get their packages. So you need to make sure that any classes that you _do not_ want to export are kept out of exported packages. Exported classes should not share a package with classes that you do not want to export.
The suggested package hierarchy (used internally for MuleSoft modules):
```
org.mule.module
\--> .api.*
\--> .internal.*
```

  * `.api.*` contains all the classes that to be exported and seen by the Mule app: Return Types, Subtypes, Input Types, and Connection interfaces.
  * `.internal.*` contains all the classes used for specific behavior of the module: Annotated classes, `Connection` and `Operation` implementations, and internal classes.


### Knowing the Exported Packages and Return Types.
MuleSoft recommends that **all** exported classes belong to the module.
To avoid library clashes that make a module incompatible with other modules, app dependencies, or even runtimes, it is _highly recommended_ that you:
  * _Never_ return or receive objects from classes that belong to a library that a module is using.


Consider the scenarios in the next sections.
#### First Scenario: Exporting the Same Packages
This scenario includes two modules with two very different operations. Both use the same library (GSON) to parse JSON and _return_ an instance of a `JsonObject` class. One of them uses GSON version `1.1`, and the other uses GSON version `2.3`. The `JsonObject` class lives in the same package in both versions, but the different implementations of each version make the classes incompatible.
This example exposes the `JsonObject` class as the return type of the operation:
First Module Operation
```
public JsonObject getEmployee(@Connection EmployeesServiceConnection connection, String id) {
 return new JsonObject(connection.getById(id));
}
```

Second Module Operation
```
public JsonObject getAllProducts(@Connection ProductsServiceConnection connection) {
 return new JsonObject(connection.getProdsJson());
}
```

When you deploy a Mule app and try to use two modules that export the same packages, Mule will fail because two modules cannot export the same package.
#### Second Scenario: Returning Two Instances of the Same Class in Different Versions
Building on the previous example, assume that the operations do not export the _GSON_ packages. Instead, they return a `java.lang.Object`.
First Module Operation
```
public Object getEmployee() {
 // Here JsonObject is from GSON 1.1
 return new JsonObject();
}
```

Second Module Operation
```
public Object getAllProducts() {
 // Here JsonObject is from GSON 2.3
 return new JsonObject();
}
```

If you use both modules in an app, only one of the two versions will be loaded for the app because both classes have exactly the same fully qualified name. So the fully qualified names will clash, and the module that needs the _unloaded_ version of the package will behave differently and be prone to errors such as `ClassCastException` or `NoSuchMethodException`.
### The @Export annotation
The `@Export` annotation can be used for extreme corner cases or complex cases in which a module needs to export a class that is not automatically exported by the SDK.
The `@Export` annotation receives an array of classes to be exported.
You cannot export a class without exporting all the classes in the same package as the exported class.   
---