Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The OgnlRuntime class stores static Map-like instances of reflection meta cache information for all objects evaluated in OGNL expressions. The new clearCache method clears these caches out as the memory footprint can get quite large after a while. How often/when to call this will largely depend on how your framework works - just keep in mind that calling it too often will have a big impact on runtime performance of your app if you are doing normal application development sort of things with it.

 HiveMindExpressionCompiler

Perhaps the most important class to examine is Tapestrys implementation of OgnlExpressionCompiler. This class still extends the default ExpressionCompiler provided by OGNL - but does a few more things that can't be made generic enough to live in the default implementation.

One of these important differences is how Javassist is used to compile the expressions and the ClassLoader/ClassResolver it uses. Because these expressions are being compiled against what are already Javassist enhanced Tapestry component class instances this implementation needed to re-use existing hivemind Javassist services so that these enhanced classes could be correctly resolved while OGNL is evaluating them.

If you don't have a need to provide this kind of classloading functionality you will probably still need to modify at least how the javassist ClassPool is being managed in your own implementations. The internal functionality of that library is such that the memory consumption of the pool is very large and will get unwieldy especially in development of web apps. Tapestry has a special state that users are used to which is known as "disable caching" - more or less meaning that javassist enhancements happen for every request instead of only once.

Another very important piece of logic that this class handles is the generation of "fail safe" getters/setters when expressions just can't be compiled because of either internal errors or a specific syntax type used isn't yet able to support javassist compilations. This logic can sometimes get tricky in that in many instances OGNL expressions won't be compilable because the full expression contains a null reference. The basic idea is that the compiler keeps trying to compile these kinds of expressions until it either gets a fatal exception thrown or the full expression is able to be resolved. For example, the following expression would throw a UnsupportedCompilationException if the "user" object returned was null - resulting in no direct compilation being done at all:

No Format

"user.firstName"

That doesn't mean that the user object might not be resolvable the next time this expression is invoked though, so the next time the compiler tries it may succeed in which case the whole expression is enhanced and the new ExpressionAccessor instance is attached to the root Node object by calling SimpleNode.setAccessor(newInstance).