The Object Teams Blog

Adding team spirit to your objects.

Posts Tagged ‘module

Jigsaw arriving – and now what?

leave a comment »

The debate is over. The result of fierce discussions has been declared. Jigsaw is knocking at the door. Now the fate of Jigsaw depends on the community. Will the community embrace Jigsaw? Will we be able to leverage the new concepts to our benefit? Will we struggle with new pitfalls?

Let’s step back a second: do we really know what is Jigsaw? Do we really understand the design, its subtleties and implications?

eclipsecon2017At EclipseCon Europe 2017 I will try to shed a light on some lesser known aspects of Jigsaw. A deep dive into things I learned as a JDT committer while implementing tool support for Java 9.

In search for truth

To set the stage, we’ll first have to figure out, who or what defines Java 9 — or Jigsaw — or JPMS. This is both a question of specification vs. implementation as well as a matter of a specification spread over several documents and artifacts. Let’s try to grok Jigsaw from the legally binding sources, rather then from secondary writing and hearsay (if that is possible).

We will have to relearn some of the basic terms, like: what is a package in Java? Do packages form a hierarchy? (I will show, how both answers, yes and no, are equally right and wrong).

Jigsaw is said to do away with some “undesirable” stuff like split packages, and cyclic dependencies. Really? (Yes and no).

Encapsulation

Of course, with Jigsaw all is about encapsulation – easy to agree on, but what is it that a Java 9 module encapsulates? Only a deep understanding of the flavor of encapsulation will tell us, what exact qualities we gain from following the new discipline (it’s not about security, e.g.), and also what pains will be incurred on the path of migrating to the new model. (Hint: I will be speaking both about compile time and runtime).

Interestingly, the magic potion Jigsaw also brings its own antidote: With tightening the rules of encapsulation, also the opposite becomes necessary: they call it breaking encapsulation, for which I once coined the term “decapsulation“. I should be flattered by how close Java 9 comes to what I call “gradual encapsulation“. So, the talk can not stop at presenting just the new language concepts, also the various extra-lingual means for tuning your architecture need to be inspected through the looking glass. This is also where tools come into focus: how can JDT empower its users to use the new options without the need to dig through the sometimes cryptic syntax of command line parameters?

Loose ends

At this point we shall agree that Jigsaw is a compromise, fulfilling many of its goals and promises, while also missing some opportunities.

I will also have to say a few words about long standing API of JDT, which makes guarantees that are no longer valid in Java 9. This raises the question: what is the migration path for tools that sit on top of JDT? (There is no free lunch).

Finally, it wouldn’t be Java, if overloading wouldn’t make things worse for the newly added concepts. But: haven’t you become fond of hating, when JDT says:

error_obj The type org.foo.Bar cannot be resolved. It is indirectly referenced from required .class files

We may be seeing light at the end of the tunnel: for Jigsaw we had to revamp the guts of our compiler in ways, that could possibly help to – finally – resolve that problem. Wish me luck …

Hope to see you in Ludwigsburg, there’s much to be discussed over coffee and beer

eclipsecon2017 Ludwigsburg, Germany · October 24 – 26, 2017

Advertisements

Written by Stephan Herrmann

September 10, 2017 at 16:31

Modularity at JavaOne 2012

leave a comment »

Those planning to attend JavaOne 2012 in San Francisco might be busy right now building their personal session schedule. So here’s what I have to offer:

On Wed., Oct. 3, I’ll speak about

Redefining Modularity and Reuse in Variants—
All with Object Teams

I'm Speaking at JavaOne 2012

I guess one of the goals behind moving Jigsaw out of the schedule for Java 8 was: to have more time to improve our understanding of modularity, right? So, why not join me when I discuss how much an object-oriented programming language can help to improve modularity.

When speaking of modularity, I don’t see this as a goal in itself, but as a means for facilitating reuse, and when speaking of reuse I’m particularly interested in reusing a module in a context that was not anticipated by the module provider (that’s what creates new value).

To give you an idea of my agenda, here’re the five main steps of this session:

  1. Warm-up: Debugging the proliferation of module concepts – will there ever be an end? Much of this follows the ideas in this post of mine.
  2. Reuse needs adaptation of existing modules for each particular usage scenario. Inheritance, OTOH, promises to support specialization. How come inheritance is not considered the primary architecture level concept for adapting reusable modules?
  3. Any attempts to apply inheritance as the sole adaptation mechanism in reuse mash-ups results in conflicts which I characterize as the Dominance of the Instantiator. To mend this contention inheritance needs a brother, with similar capabilities but much more dynamic and thus flexible.
  4. Modularity is about strictly enforced boundaries – good. However, the rules imposed by this regime can only deliver their true power if we’re also able to express limited exceptions.
  5. Given that creating variants and adapting existing modules is crucial for unanticipated reuse, how can those adaptations themselves be developed as modules?

At each step I will outline a powerful solution as provided by Object Teams.

See you in San Francisco!

5 items in your shopping cart Edit: The slides and the recording of this presentation are now available online.

Written by Stephan Herrmann

September 20, 2012 at 19:55

How many concepts for modules do we need?

with 13 comments

The basic elements of programming are methods. If you have many methods you want to group them in classes. If you have many classes you want to group them in packages. If you have many packages you want to group them in bundles. If you have many bundles you group them in features, but if you have many features …stop!, STOP!!!

Isn’t this insane? Every time we scale up to the next level we need a new programming concept? Like, someone invented the +1 operator and I can trump him by inventing a +2 operator, and you trump me by …? Haven’t we learned the 101 of programming: abstraction? I guess not many folks in Java-land are aware of a language called gbeta, where classes and methods are unified to “patterns” and no other kinds of modules are needed than patterns. It’s good news that the guy behind gbeta receives one of this year’s prestigious Dahl-Nygaard prizes: Erik Ernst. Object Teams owes much to Erik and I will speak more about his contributions in a sequel post.

Another really smart guy is Gilad Bracha, who after working on Java generics (together with Erik actually) and even JSR 294 decided to do something better, actually doubleplusgood. While he upholds the distinction between methods and classes he makes strong claims that no other modules than classes are needed, if, and here is the rub: if classes can be nested (see “Modules as Objects in Newspeak“).

Modules in Java: man or boy?

Let me briefly check this hypothesis:

The proliferation of module concepts in Java is due to the lack of truly nestable modules.

Which of the above mentioned concepts supports nesting? Features support inclusion which isn’t exactly nesting, but since features are actually defied by OSGi purists, I don’t want to burn my fingers by promoting features. Bundles cannot be nested, bummer! Some people actually think packages support nesting, with two reasons for believing so: packages are mapped to directories in a files system or in a jar and directories can be nested, plus: packages have compound names. However, semantically the dot in a package name is just a regular part of the name, it has no special semantics. Speaking of package foo.bar being a “sub-package” of foo is strongly misleading as the relation between them two is in no way different from the relation between any other pair of packages. All packages are equalst. Perhaps you recall the superpackage hero (or
the strawman of that hero), which introduced the capability that a public class can actually be seen by classes from specific superpackages only. And: superpackages where designed to support nesting. Now superpackages are “superceded” by Jigsaw modules, which don’t support nesting. Great, they invented the +3 operator. That’s award winning!

Finally classes: surprisingly, yes, classes can be nested. Unfortunately, still today it shines through that nested classes are an after-thought, the real core of Java 1.0 was designed without that. E.g., serializing nested classes is strongly discouraged. How many O/R mappers support non-static inner classes? The last time I looked: zero!

Nested classes: flaws and remedies (part 1)

I see three conceptual flaws in the design of nested classes in Java:

  1. scoping (2 problems actually)
  2. forced representation
  3. poor integration with inheritance

I discuss the first two in this post, the third, inheritance, deserves a post on its own right.
For each problem I will briefly show how it is resolved in OT/J. First off, I should mention that OT/J maintains compatibility with Java by applying any modified semantics only inside classes with the team modifier.

Scoping

Consider the following Java snippet:

public class City {
   TownHall theTownHall = new TownHall();
   class TownHall {
       class Candidate { }
       Candidate[] candidates;
       void voteForMayor(Candidate candidate) { ... }
   }
   class Citizen {
       void performCivilDuties() {
           ...
           theTownHall.voteForMayor(theTownHall.candidates[n]);
       }
   }
}
 

In this code we can actually make all methods, fields and nested classes private, to the end that external clients see none of these internal details of a City, whereas classes at the inside can blithely communicate with each other. Thus we have created a wonderful module City which can use all accomplishments of object-oriented programming for its internal structure – well hidden from the outside. In Java, however, this is flawed in two ways:

  1. Nested classes cannot protect any members from access by sibling classes, so I (a Citizen) can actually see the wallets of all mayor Candidates (well, maybe that’s not a bug but a feature). It would be much more useful if only inside-out visibility was given, i.e., a Citizen can see all members of his/her City, but not inverse – the City looking into its glass Citizens.
  2. Scoping rules in Java are purely static, i.e., permissions are given to classes not objects. As a result I could not only vote in my home city, but in any City (and every person can see the wallet of any other person etc.).

OT/J solves (1) by reinterpreting the access modifiers. Within a team class a private field Candidate.wallet, e.g., would not be visible outside its class, whereas a Citizen could still access theTownHall if this field were private.

(2) is basically solved by applying different rules to self-references (incl. outer self) than to explicitly qualified expressions, so City.this.theTownHall (OK, uses the enclosing this instance) applies different rules than newYork.theTownHall (not OK if theTownHall is private).

Well, issue (1) is a matter of tedious details, where I see no excuse for Java’s “solution”. Issue (2) has always been a differentiation between good old Eiffel, e.g., and its “successor” Java. This issue stands for a conceptual crossroad: are we interested in code nesting, or are we more interested in expressing how run-time objects are grouped? I personally don’t see much use in making the definition of a Citizen a nested part of the definition of a City, but speaking of many Citizens (instances) forming a City (instance) makes a lot of sense.

Forced Representation

By this I mean the fact that programmers are forced to store all inner classes textually embedded in their enclosing class. After we’ve already seen the discrepancy between the semantics and the representation of a package (flat structure stored in nested directories), now we see the opposite: semantic nesting is forcefully tied to representational nesting. This sounds logical until you start to write significant amounts of code as one big outer class with lots of (deeply) nested classes contained. You probably wouldn’t even think of this, because pretty soon the file becomes unmanageably huge. This is a very mundane reason why class nesting in Java simply doesn’t scale.

The solution in OT/J is pretty trivial. The following structure

// file community/City.java
package community;
public team class City {
    protected class Citizen {}
}
 

is strictly equivalent to these two files:

// file community/City.java
package community;
/**
 * @role Citizen
 */
public team class City {
}
 
// file community/City/Citizen.java
team package community.City;
protected class Citizen {}
 

The trick is: City is both a class and a special package. So semantically the team contains the nested Citizen but physical storage may happen in a separate file stored in a directory community/City/ that corresponds to the enclosing team class.

As a special treat the package explorer of the OTDT provides two display options for team packages: logical vs. physical. In the physical view the 2-files solution looks like this:

Just by selecting the logical view, where the team-package is not shown, the display changes to

Small files in separate directories are good for team support etc. Logical nesting is good for modularity. Why not have the cake and eat it?

These are just little tricks introduced by OT/J and the OTDT. But with these there’s no excuse any longer for not using class nesting even for large structures. And remember: this is real nesting, so you can use the same concept for 1-level, 2-level, … n-level containment. Good news for developers, bad news for technology designers, because now we simply don’t need any “superpackages”, “modules” etc. I actually wonder, how nestable classes could be unified with bundles, but that’s still a different story to be told on a different day.

Before that I will discuss how nesting and inheritance produce tremendous synergy (instead of awkwardly standing side-by-side). From a research perspective this has been solved some 9 years ago. I strongly believe that the time is ripe to bring these fruits from ivory towers to the hands of real world developers. Stay tuned for part 2.

Written by Stephan Herrmann

March 20, 2010 at 22:50