The Object Teams Blog

Adding team spirit to your objects.

Archive for the ‘OTJLD’ Category

Object Teams now has Lambdas (and more)

leave a comment »

In a previous post I announced that the Luna version of Object Teams will incorporate support for Java 8.

Now that the big rush towards March 18 is over, I took stock how Object Teams fits into the Luna stream, which finally contains all the bits for Java 8 support. The result:

We have our first builds with full support for OT/J on Java 8!

This means, you can now use lambda expressions and more even in OT/J programs, here’s a witness:

Lambda In Parameter Mapping

While this program may not make a lot of sense, it demonstrates a funny piece of syntax. Here’s what you see:

  • The regular class PersonCollection offers a method restrict that takes an argument of a functional type (Predicate)
  • Role Club.Members is played by PersonCollection and makes the base method available via a callout binding (lines 19 f)
  • The role wants to pass just an int value, where the base method expects a Predicate.
  • This incompatibility is bridged by a parameter mapping that maps a lambda expression to the expected parameter (line 20).

This looks funny, because two different uses of the token -> meet on a single line: the first -> is part of the lambda expression, separating the parameter from the body, the second -> is part of the parameter mapping, mapping the expression on the left to the parameter on the right.

Were I to chose the syntax in a green field situation, I would certainly not use the same token for such different purposes. But since we’re basically merging two independent language extensions I had no choice. After some worries that the combined language might not be parseable I’m much relieved to see it actually working!

A very similar situation actually exists concerning type annotations. More on that in a future post.

Remaining steps towards Luna

Merging the entire BETA_JAVA8 code base from JDT into Object Teams is done, but a few regressions (< 30 out of 84,000+ tests) remain from that exercise. But compared to the original JDT efforts for Java 8 this truly is peanuts 🙂

We only have one hurdle still to jump: our bytecode weaver is based on BCEL, for which no update for Java 8 is in sight. This means: we cannot weave into class files that use the Java 8 bytecode version, bummer!

So the real interesting question will be: can we get the long announced alternate weaver using ASM up to speed in time for Luna? I think we can, but it won’t hurt if you wish me luck in this endeavour.

And yes: one day I should start writing meaningful examples using Java 8 features in OT/J code…

Advertisements

Written by Stephan Herrmann

March 30, 2014 at 23:44

Posted in Eclipse, Object Teams, OTDT, OTJLD

Tagged with ,

Book chapter published: Confined Roles and Decapsulation in Object Teams — Contradiction or Synergy?

leave a comment »

I strongly believe that for perfect modularity, encapsulation in plain Java is both too weak and too strong. This is the fundamental assumption behind a book chapter that has just been published by Springer.

The book is:
Aliasing in Object-Oriented Programming. Types, Analysis and Verification
My chapter is:
Confined Roles and Decapsulation in Object Teams — Contradiction or Synergy?

The concepts in this chapter relate back to the academic part of my career, but all of my more pragmatic tasks since those days indicate that we are still very far away from optimal modularity, and both mistakes are found in real world software: to permit access too openly and to restrict access too strictly. More often than not, it’s the same software exhibiting both mistakes at once.

For the reader unfamiliar with the notions of alias control etc., let me borrow from the introduction of the book:

Aliasing occurs when two or more references to an object exist within the object graph of a running program. Although aliasing is essential in object-oriented programming as it allows programmers to implement designs involving sharing, it is problematic because its presence makes it difficult to reason about the object at the end of an alias—via an alias, an object’s state can change underfoot.

978-3-642-36946-9

Aliasing, by the way, is one of the reasons, why analysis for @Nullable fields is a thorny issue. If alias control could be applied to @Nullable fields in Java, much better static analysis would be possible.


How is encapsulation in Java too weak?

Java only allows to protect code, not objects

This manifests at two levels:

Member access across instances

In a previous post I mentioned that the strongest encapsulation in Java – using the private modifier – doesn’t help to protect a person’s wallet against access from any other person. This is a legacy from the pre-object-oriented days of structured programming. In terms of encapsulation, a Java class is a module utterly unaware of the concept of instantiation. This defect is even more frustrating as better precedents (think of Eiffel) have been set before the inception of Java.

A type system that is aware of instances, not just classes, is a prerequisite for any kind of alias control.

Object access meets polymorphism

Assume you declare a class as private because you want to keep a particular thing absolutely local to the current module. Does such a declaration provide sufficient protection? No. That private class may just extend another – public – class or implement a public interface. By using polymorphism (an invisible type widening suffices) an instance of the private class can still be passed around in the entire program – by its public super type. As you can see, applying private at the class level, doesn’t make any objects private, only this particular class is. Since every class extends at least Object there is no way to confine an object to a given module; by widening all objects are always visible to all parts of the program. Put dynamic binding of method calls into the mix, and all kinds of “interesting” effects can be “achieved” on an object, whose class is “secured” by the private keyword.

The type system of OT/J supports instance-based protection.

Java’s deficiencies outlined above are overcome in OT/J by two major concepts:

Dependent types
Any role class is a property of the enclosing team instance. The type system allows reasoning about how a role is owned by this enclosing team instance. (read the spec: 1.2.2)
Confined roles
The possible leak by widening can be prevented by sub-classing a predefined role class Confined which does not extend Object. (read the spec: 7.2)

For details of the type system, why it is suitable for mending the given problems, and why it doesn’t hurt in day-to-day programming, I have to refer you to the book chapter.


How is encapsulation in Java too strict?

If you are a developer with a protective attitude towards “your” code, you will make a lot of things private. Good for you, you’ve created (relatively) well encapsulated software.
But when someone else is trying to make use of “your” code (re-use) in a slightly unanticipated setting (calling for unanticipated adaptations), guess what: s/he’ll curse you for your protective attitude.
Have you ever tried to re-use an existing class and failed, because some **** detail was private and there was simply no way to access or override that particular piece? When you’ve been in this situation before, you’ll know there are basically 2 answers:

  1. Give up, simply don’t use that (overly?) protective class and recode the thing (which more often than not causes a ripple effect: want to copy one method, end up copying 5 or more classes). Object-orientation is strong on re-use, heh?
  2. Use brute force and don’t tell anybody (tools that come in handy are: binary editing the class file, or calling Method.setAccessible(true)). I’m not quite sure why I keep thinking of Core Wars as I write this 🙂 .

OT/J opens doors for negotiation, rather than arms race & battle

The Object Teams solution rests on two pillars:

  1. Give a name to the act of disregarding an encapsulation boundary: decapsulation. Provide the technical means to punch tiny little holes into the armor of a class / an object. Make this explicit so you can talk and reason about the extent of decapsulation. (read the spec: 2.1.2(c))
  2. Separate technical possibility from questions of what is / should / shouln’t be allowed. Don’t let technology dictate rules but make it possible to formulate and enforce such rules on top of the existing technology.

Knowing that this topic is controversial I leave at this for now (a previous discussion in this field can be found here).


Putting it all together

  1. If you want to protect your objects, do so using concepts that are stronger than Java’s “private”.
  2. Using decapsulation where needed fosters effective re-use without the need for “speculative API”, i.e., making things public “just in case”.
  3. Dependent types and confined roles are a pragmatic entry into the realm of programs that can be statically analysed, and strong guarantees be given by such analysis.
  4. Don’t let technology dictate the rules, we need to put the relevant stakeholders back into focus: Module providers, application developers and end users have different views. Technology should just empower each of them to get their job done, and facilitate transparency and analyzability where desired.

Some of this may be surprising, some may sound like a purely academic exercise, but I’m convinced that the above ingredients as supported in OT/J support the development of complex modular systems, with an unprecedented low effective coupling.

FYI, here’re the section headings of my chapter:

  1. Many Faces of Modularity
  2. Confined Roles
    1. Safe Polymorphism
    2. From Confined Types to Confined Roles
    3. Adding Basic Flexibility to Confined Roles
  3. Non-hierarchical Structures
    1. Role Playing
    2. Translation Polymorphism
  4. Separate Worlds, Yet Connected
    1. Layered Designs
    2. Improving Encapsulation by Means of Decapsulation
    3. Zero Reference Roles
    4. Connecting Architecture Levels
  5. Instances and Dynamism
  6. Practical Experience
    1. Initial Comparative Study
    2. Application in Tool Smithing
  7. Related Work
    1. Nesting, Virtual Classes, Dependent Types
    2. Multi-dimensional Separation of Concerns
    3. Modules for Alias Control
  8. Conclusion

Written by Stephan Herrmann

March 30, 2013 at 22:11

Meta Feedback

leave a comment »

Last Friday I received some wonderful meta-feedback. What’s that you’ll say?
It’s feedback on feedback, or, second order feedback.

First Order Feedback

Initially, I’m thinking of feedback whereby a tool tells its user what s/he’s done wrong and where to go in order to improve. As I mentioned earlier, I’m not interested in a tool that just works when it works, as that might require its users to get everything 100% correct right from the beginning. In our business I’m interested in tools that help the user to get it to work, from initial buggy attempts towards a full working solution.

So, when working on the Object Teams Development Tooling, how can we make the tool speak to the user in really helpful ways?

First we really care to give precise error messages and warnings regarding all kinds of situations that look funny, strange or plain bogus. Last time I counted the OT/J compiler featured 314 messages specific to OT/J. This is excellent for a seasoned OT/J developer but someone still trying to learn the language might be a little bit puzzled by messages like:

Fragile callin binding: base method requires a result of type {0}, which is not provided in this binding. If no base call is issued, the result will be missing, causing a ResultNotProvidedException to be thrown (OTJLD 4.3(e)).

The clue on how to help the puzzled users lies in the suffix “OTJLD 4.3(e)”: that’s exactly the paragraph in the OT/J Language Definition, that defines what’s going on here. But what’s a reference like “§4.3(e)” good for? So the next thing we added to the OTDT was a context menu action on any OT/J related problem in the Problems view:

What do you see:

  • At the top you see an editor with an underlined, buggy piece of code
  • Next you see the Problems view with the corresponding error message
  • Next you see a context menu on the problem with an entry “Go to Language Definition“.
  • At the bottom finally you see a small extract from the language definition, exactly that paragraph that is violated by the buggy code. If that doesn’t provide sufficient context there are plenty of hyperlinks and breadcrumbs that help to find the required explanation

This is our specific feedback system and I think its already quite nice, however …

Second Order Feedback

Last Friday I presented Object Teams at the Vienna Helios Demo Camp. When I showed the “Go to Language Definition” action Peter Kofler gave some excellent feedback on our feedback system. He must have feeled the too-much-stuff syndrome you can easily see when looking at the screenshot above. So he requested that the same action be available even without the Problems view. So once back home I file bug 318071. In the most recent build you now have two more options:

Use the context menu of the left gutter:

Use the toolbar of the problem hover

Need I say that adding a button to the problem hover is not normally possible? With the action already in place the following OT/J code is all we need to integrate into the JDT/UI’s implementation of that hover:

/**
 * Add OT-Support to hovers for java problems.
 *  
 * @author stephan
 * @since 0.7.0 (Incubation at Eclipse.org)
 */
@SuppressWarnings({ "restriction", "decapsulation" })
public team class HoverAdaptor {
 
        /** Add the "Go to Language Definition" action to the hover's toolbar. */
        protected class ProblemHoverAdaptor playedBy ProblemInfo {
 
                void addAction(ToolBarManager manager, Annotation annotation) <- after void fillToolBar(ToolBarManager manager, IInformationControl infoControl)
                        base when (isOTJProblem(base.annotation))
                        with {  manager    <- manager,
                                        annotation <- base.annotation }
 
                void addAction(ToolBarManager manager, Annotation annotation) 
                {
                        manager.add(ShowOTJLDAction.createAction(null/*site*/, annotation.getText()));
                }
 
                static boolean isOTJProblem(Annotation annotation) {
                        if (annotation instanceof IJavaAnnotation) {
                                int problemId = ((IJavaAnnotation) annotation).getId();
                                return problemId > IProblem.OTJ_RELATED && problemId < IProblem.TypeRelated;
                        }
                        return false;
                }
        }
}
 

Thanks Peter, I think your RFE made a clear point for usability of the OTDT!

Written by Stephan Herrmann

June 28, 2010 at 16:38

Posted in Eclipse, Object Teams, OTDT, OTJLD

Tagged with ,