The following is a list of the current known restrictions in Stomp. Many of these will be removed transparently as Stomp matures, but a few may not. See the prognosis for each for more details. Of course, if any of these bugs is mission critical for your application, you may be able to fix it yourself. Email me (firstname.lastname@example.org) for more detailed information about how to attack these. You can also drop me a line to try to convince me to get on some of these, but I can’t promise anything J.
Things in black are current issues.
Things in orange are old issues that have been fixed. They are included to give you an idea of where Stomp has been, where it might be headed, and how accurate the original prognosis was…
The (probably) permanent problems:
- Static blocks get evaluated during enhancement.
o Description: Enhanced classes are loaded during enhancement in order to get at their bytecode and modify it. This can result in side-effects that make sense at runtime but not at enhancement time.
o Prognosis: Bad. This will likely be a problem for a long time. If you wanted to remove this restriction, you’d have to re-implement several features of the Serp bytecode toolkit so that it could do all its work without ever using a Class.forName. I believe this is possible, but realistically not going to happen any time soon.
o Work-around: Fortunately, it’s almost always possible to move problem code out of static blocks. Try instantiating variables lazily, having a startup function that gets called when you start up the application, etc.
- Private methods are made protected during enhancement
o Description: Like the name says. This could be a problem if you are using the private keyword as a runtime security measure, and not just a tag to inform other developers that you don’t mean for them to call the method directly (note that the private keyword will still be around at compile time, so it still accomplishes this last goal).
o Prognosis: Bad. This may always be a problem. Since Serp breaks up one logical entity into two classes, a proxy and a delegate. The proxy needs to be able to invoke the private method in the delegate and vice versa. I am not aware of a Java mechanism that would allow only a single class access rights to a method.
o Work-around: Use some other means to secure your runtime application.
Known issues that should be resolved in time:
- (Solved 2002.10.7) Line numbers are not available in stack traces for enhanced objects.
o Description: The line number table is not correctly setup for the delegate in the proxy-delegate pair. Stack traces say something like (Unknown Source) where a line number would normally be found.
o Prognosis: Good. I’m not sure why it doesn’t work right now. It should just be a matter of hunting down the bug in transferring the line number table to the new class file. The line number table itself should not require any modifications, apart from keeping the targets setup correctly.
o Work-around: Not available.
- Have to enhance entire object hierarchy.
o Description: Unlike JDO, which allows different parts of the inheritance tree to be enhanced independently, stomped classes have to have the entire tree enhanced. In particular, this means that persistent classes cannot extend any objects in the standard java libraries.
o Prognosis: Unclear. I haven’t spent too much time thinking about how to get around this, since I can’t imagine using this feature myself. More research is needed.
o Work-around: Use a “contains” relationship to parent classes that you might have preferred to extend.
- No support for direct access to non-static member variables in enhanced classes.
o Description: If you declare a member variable in an enhanced class public or protected, and access it directly from a non-enhanced class, method calls made on the object will not be enhanced.
o Prognosis: Very good. The only reason this isn’t already in there is that you really should never do this anyways, and it might be better not to turn on this ‘feature’ at all.
o Work-around: Don’t access member variables directly from other classes. Use getters and setters.
- No support for altering contents of a Collection outside persistent class.
o Description: A persistent object returns a Collection that represents persistent data to some other object. This other object modifies the collection. This results in a JDOException, since no Transaction is started.
o Prognosis: Good. It is theoretically possible to intercept these calls and start transactions (and other method-level services) as appropriate. It just hasn’t been implemented yet.
o Work-around: The truth is, you shouldn’t do this anyways. Keep your data private, and provide mutator methods that do the work inside the persistent object.
- (Solved 2004.11.17)‘This’ pointer not fully supported transparently. Can’t enhance non-static inner classes.
o Description: Stomp breaks a single class into a proxy-delegate pair. The problem is that when a developer uses the ‘this’ pointer, sometimes this logically refers to the delegate, and sometimes this logically refers to the proxy. Currently, ‘this’ is often left to mean the delegate. This can cause problem in which an object obtains a handle to a delegate, when it really should have a handle to a proxy, as in the following cases: when ‘this’ is returned from a method, passing ‘this’ as an argument in a method call, non-static inner-class constructors.
o Prognosis: Good. Analyzing the bytecode to find these cases is complicated, but progress has already been made with the StackAnalyzer.
o Work-around: Use WrapperFactory.singleton ().wrap (this) whenever you would otherwise have returned ‘this’ from a method or passed ‘this’ as an argument to a method. Use static inner-classes, but pass an argument to the enclosing object in the constructor call (using WrapperFactory.wrap (this) of course…).
- (Solved – 2002.9.3) Can’t use ‘switch’ statements in enhanced objects.
o Description: Limitation of the StackAnalyzer prevents use of switch statements.
o Prognosis: Very good. This should not be difficult once there is time to get it done.
o Work-around: Replace switch statements with if/else blocks.
- (Solved 2004.11.15) Can’t use ‘this’ pointer in ‘catch’ blocks.
o Description: A combination of poor support for ‘jump’ statements in the StackAnalyzer, and complexities surrounding the ‘this’ pointer, make it the case that using the ‘this’ pointer (even implicitly, like calling a non-static method of ‘this’) in catch blocks is forbidden. The result is invalid bytecode.
o Prognosis: Very good. As with support for switch statements and transparently handling ‘this’, this bug simply involves making the StackAnalyzer more robust.
o Work-around: Case-by-case.
- Private / protected / static methods are not serviced.
o Description: Only public, non-static methods receive the benefits of the Stomp service layer. In particular, if you have a protected method that changes persistent fields, you’ll run into JDOExceptions because no transaction will have been started.
o Prognosis: OK. There is no theoretical reason why these methods can’t be serviced; it just doesn’t fit naturally into the current design. The proxy will have to become more intelligent about how it delegates these method calls.
o Work-around: Use singleton patterns in place of static classes. Make protected mutator methods public (ouch), or handle the transaction management yourself inside this method (calling JDOFactory.getTransactionalPersistenceManager (), etc).
- Can’t use the ‘declareImports’ feature of JDO queries
o Description: Stomp needs to convert variable and parameters defined in queries to use the name of the generated delegate, not the proxy. Currently this works from a simple String lookup, which requires the fully qualified name of the class.
o Prognosis: OK. There is no reason this couldn’t be done, the information is certainly available, and any JDO1.0 compliant implementation must have code that basically does this already implemented. The only reason it may not come immediately is that I don’t have that code, and this feature doesn’t seem worth the time right now (see list of other restrictions above). Maybe some kind JDO vendor will implement this for us…
o Work-around: Remove calls to query.declareImports, and instead use fully qualified names in your filter, parameter, and variable declarations.