Lesson 7: Exclude Types From a Model
Invariably, you will run into situations where there are Java types that you are just not interested in, yet they keep appearing in your model because they are referenced by types that you are interested in. You are absolutely certain that you will never want to generate proxy types for these types and having them in your model makes everything consume more resources, take longer, and makes the model harder to understand.
To alleviate this problem, the code generator allows you to exclude Java types from import operations. Basically, whenever you import Java types into the model, excluded types are simply omitted. It is not as if they were missing but rather as if they did not exist at all.
The code generator is already configured to exclude some types. Here is the default value of the "Excluded Types" model property:
{ exclude:'com.sun.**,sun.**,sunw.**', private:false, anonymous:false, annotation:false }
This instructs the code generator to omit the internal Java implementation types that come with every JRE (in SUN packages) as well as private types, anonymous types, and annotation types. This is a good default value because explicit use of these types is either strongly discouraged or impossible, even in pure Java.
You can change the value of this property to omit fewer, more, or different types from the model. For example:
you might have a very strong type naming policy for your own Java types. Any type whose name ends with Impl
might be an
implementation type that should not be considered for proxy generation because you only want to generate API types
and not implementation types. You could modify the Excluded Types property to:
{
exclude:'com.sun.**,sun.**,sunw.**,com.myfirm.**Impl',
private:false,
anonymous:false,
annotation:false
}
Step by Step Instructions
- Start the Code Generator GUI
To start the code generator, run
xmog
without the-version
argument. Assuming you are still in the code generator'sbin
directory, simply type:xmog
./xmog
If you run into problems please check out the first lesson.
- Open the Import Type(s) from Classpath Dialog
Click the toolbar icon or select Import Type(s) from Class Path... from the code generator's Edit menu. You should see this dialog displayed:
- Specify the Types You Want to Import
We are just going to import all the types in the
java.lang
package, so we leave the Exclude field blank and enterjava.lang.*
in the Include field. Press OK.You should see something like this:
We will focus on the types whose name starts with
Class
. You can see that there are several enabled types (Class
,ClassCastException
,ClassLoader
, etc.) as well as a few disabled types (ClassCircularityError
,ClassFormatError
). Your exact results may vary based on the JRE you have configured.It's a bit contrived, but let's say that we never want to see these
Class
-related types in our model again. That's easily achievable via the Exclude Types model property. - Start Over
Close the code generator without saving the model and start over with a new model by repeating Step 1.
- Modify the Excluded Types Property
Click in the new model's edit field for the "Excluded Types" model property. Change the exclude value by prepending
java.lang.Class*,
. This will prevent any types in thejava.lang
package whose name starts withClass
from appearing in the model. The new value should look like this:{exclude:'java.lang.Class*,com.sun.**,sun.**,sunw.**', private:false, anonymous:false, annotation:false }
- Import Types
Repeat Step 2 to perform the import operation of all types in the
java.lang
package. The resulting model will now look something like this:Note that all the types whose names start with
Class
are gone from the model. They are gone because these types satisfy the modified exclusion condition. Of course these types continue to exist as Java types and they will always be present in Java. It is simply our model that has been made unaware of the types' continued existence. Any code generation taking place now would not include any reference to the excluded types.You can't see it in the screenshot, but if there were types starting with
Class
in other packages, they would still be there. This is because we specified that we only wanted to exclude types starting withClass
in thejava.lang
package. Had we wanted to exclude all types whose name starts withClass
irrespective of their package, we could have used the pattern**.Class*
.
Take-Away Points
- When You Should Consider Type Exclusion
Beyond the types excluded by the default setting, you would typically consider excluding types by package. Frequently, you have entire packages that are of no interest for an integration project because they contain only types that deal with application internals like logging or tracing. There might also be packages that contain code that you don't want to expose, like application security. Not having such types be part of the model makes it much harder to accidentally enable them at a later point.
You might also exclude all types that follow a certain naming policy. For example, you might have application internal class types that implement the interfaces that you wish to publish to another language via the code generator. Unfortunately, the implementation classes are in the same packages as the interfaces they implement so you cannot use a package pattern to exclude them. Fortunately, all your implementation classes follow the simple naming pattern
<IfcName>Impl
. This allows you to use an exclusion pattern ofcom.myapp.**Impl
to exclude all types that are in your application's package hierarchy and whose name ends withImpl
. - When You Should Make Type Exclusion Less Restrictive
There are a few cases where you might need to generate proxy types for types in the
com.sun
orsun
packages. These cases typically involve use of types dealing with embedding Java GUI widgets in native GUI applications. Other than that, we have not yet encountered a legitimate use case for taking these types off the exclusion list. - Feel Free to Use Type Name Patterns Liberally in Type Exclusion!
>Whenever we have run into a good use case for type exclusion, it has been name pattern based. Think of examples like:
- all types whose name ends with ____,
- all types in package ____.
- How Is Type Exclusion Related to type Enablement?
The two are related, but different. Only enabled types result in generated code. To be enabled, a type must be part of the model. To be part of the model, it must not be excluded. Type exclusion is the "nuclear option" of type disabling. If a type is excluded, it can never be enabled because there is nothing in the model that to be enabled. If a type is part of the model but it is disabled, it can be enabled as we have seen in lesson on type enablement.