
\Ssect{Hyper/J Solution}{hj}

{\hj}  is designed for capturing and manipulating slices of concerns.
HyperSlices are extracted from compiled applications, and composed
into runnable applications.  An interesting property of {\hj} is that
HyperSlices are in pure Java, with \emph{all} concern related information
in the HyperModule file.  This both helps and hampers readability.
Each concern becomes very easy to understand, but we must look elsewhere
to understand even the rudiments of how the concerns (can) fit together.
Additionally, it means that concepts that should be separate become
intertwined.  An example is the use of \keywrd{abstract} to denote both
that  method should be overridden by subclasses and that the method is
in the required interface of the HyperSlice.

\johan{guessing at slice/module terminology}

\begin{figure*}
\scalefigfrom{0.25}{hjcache}
\caption{A graphical representation of the {\hj} solution}
\label{Fig:hjcache}
\end{figure*} 

{\hj} labels a set of classes a HyperSlice, and constructs new HyperSlices by composing several such slices together using a HyperModule specification.  
Deferred behavior (typically abstract methods) from one slice may be implemented in another: in general, within a composed class, a member can be replaced with another of the same signature.  
Some capabilities are provided to insert behavior before or after executions of a method, but to control the method's execution is quite complicated. 

The {\hj} solution is illustrated in \Ref{Fig}{hjcache}.  
{\hj}'s powerful composition mechanisms make it straight-forward to create reusable slices. 
While different in implementation, the design is very close to the {\aj} solution.  
It consists of four constituent HyperSlices: \collab{Base}, \collab{Back}, \collab{Cache}, and \collab{Adapt}, generating the composed HyperSlice \collab{CachedComputation}.  
Each of the constituent slices is a separately compiled Java package.  
%% Nov 15: s/check/weight/g -- This is done in several place in this file
Italic names indicate that the member is deferred: in most cases, this means that we will be providing an implementation from another slice, but in the case of \java{Item.weight} (in \collab{Base} or \collab{CachedComputation}), this merely indicates a normal \keywrd{abstract} method.%
~\footnote{%
        {\hj} provides several mechanisms for creating deferred members,
        among which \keywrd{abstract} is one.  Another is to declare
        the method as throwing a {\hj}-specific exception (these have
        been identified by the use of {\tt <<deferred>>} annotations).
        Use of abstract makes it statically obvious when a method is
        deferred, but hinders the class from being instantiated.  Use of
        the sentinel exception allows instantiation, but makes it harder
        to detect when a class is incomplete, with some deferred members
        not-yet implemented.}

The {\color{green}thick, dashed, arrows} indicate composition of classes:
as we see, all classes are composed into the same hierarchy as the base.
We also notice that each composed class contains the union of all the
members from its constituent classes.

%% Nov 15: s/check/weight/ NB: we are punting on WHICH weight method we change -- I don't know!

The {\color{magenta}rounded arrows} on the left-hand side of classes
in the composed slice indicate how references have been redirected.
For example, all references to \java{\itshape allInvalidated} are
redirected to \java{allContainers}.  The situations for \java{addItem}
and \java{weight} are slightly more complicated.  We set up
\java{addItem} to bracket all invocations with \java{associateBefore}
and \java{associateAfter}.  The original body of \java{weight} is
renamed \java{oldcachedmethod}, while the method \java{newcachedmethod}
is renamed to \java{weight}.  The result of this switch-around is
that all method calls to (the former) \java{weight} will now go to
\java{newcachedmethod} instead, which can invoke the original method
via the name \java{oldcachedmethod}.



%********************************************************************************************
%********************************************************************************************
%********************************************************************************************
%********************************************************************************************

\Ssect{Hyper/J Code}{hjcode}

%%  Nov 15: fixed
%\johan{IMPORTANT: check whether cached value should return a boolean.. isn't it supposed to be an int? what about that reference to clearCahce?}

%Hyper/J  is designed for capturing and manipulating slices of concerns. 
%HyperSlices are extracted from compiled applications, and composed into running applications. 
%The {\hj} solution for our scenario is structurally very similar to that of {\ac}s, but we will find that small differences in semantics give the result a distinctly different flavor.  
%An interesting property of {\hj} is that all examples are pure Java, with \emph{all} concern related information in the HyperModule file.
%This both hampers and helps readability. 
%Each concern becomes very easy to understand, but we must look elsewhere to understand even the rudiments of how the concerns [can] fit together. 

%% -----------------------------

\sssect{The Caching hypermodule in {\hj}}


Caching relies on ``around'' advice, which {\hj} does not have, so we
must simulate this behavior.

\lstinputlisting[caption={Cache a method in {\hj}.},label=Listing:hypercaching,float=\fl]{examples/hj/cache/C.java}

There are two ways to achieve the required ``around'' behavior in
{\hj}: splitting the ``around'' into ``before'' and ``after'' advice,
or manually mapping the advised method into the HyperSlice, so that it
can be invoked explicitly.

Manual mapping gives the concern much more flexibility as to how to affect
the wrapped method, but hampers reuse by requiring us to know the exact
signature of the wrapped method.  Caching (\Listing{hypercaching}) differs
markedly from the {\aj} (\Ref{Section}{aj}) and ({\ac} (\Ref{Section}{ac})
versions), as it illustrates manually mapping the intercepted method call
into the concern.

%forward reference to ac and hj

{\hj} is able to provide access to the result of method invocation
without needing to capture the bracketed method explicitly, but as we
additionally need to be able to control \emph{whether} the bracketed
method is invoked at all, we must make it explicit in the concern.
This in turn implies that we must hard-wire the exact signature of the
method we are caching.  Peeking ahead, we intend that the original
\java{weight} method on \type{base.Container} be hidden somehow and
composed with \java{oldcachedmeth} (\Line{hypercaching}{ocm}), and
\java{newcachedmeth} (\Line{hypercaching}{ncm}) to become the one visible
as \java{weight}.  This allows the caching behavior to invoke the original
behavior (\Line{hypercaching}{invk}) when necessary.  Setting this up
is possible, but somewhat cumbersome, and requires features that are not
available in the current release of {\hj}.  However, the developers have
kindly furnished us with a pre-release version that is able to perform
this mapping.
%% Nov 15: surely they have released that version by now?

Notable also is that we have chosen to use the \keywrd{abstract}
to indicate that the \java{allInvalidated} method
(\Line{hypercaching}{allinv}) is required.  Unlike fields, where
comments are the only option, methods can be annotated as required
either by declaring them abstract, or else implemented to throw the
{\hj}-specific UnimplementedError exception.  This sentinel exception
is recognized by the composition system to indicate a deferred method,
and thus the stub method body is omitted when two methods are composed.
The benefit of using the sentinel approach is that the class remains
instantiatable, while the abstract method approach has the benefit that
it is statically obvious that some method in the class is deferred.
The latter approach suffers from the additional drawback of forcing each
subclass of the abstract class to be abstract as well, even if they have
no abstract methods, as they inherit the deferred method, which they
cannot override, as that would hide the behavior the deferred member is
supposed to receive through composition.

% -----------------------------
% -----------------------------

\sssect{The Backlink hypermodule in {\hj}}
%%%
%%% DL Nov 17: changed title
%%% JO Nov 17: Not sure it is a hypermodule. Hyperslice? I can never remember the difference
%%%

\Listing{hyperback} shows the {\hj} implementation of the backlink concern.  
The most striking difference from the {\aj} and {\ac} versions is that \java{associate} is here split into two methods.  
We simulate ``around'' advice by splitting it into  ``before'' and ``after'' advice to a method.  
Splitting allows the concern to remain oblivious to the signature of the wrapped method, but is only applicable when the inner method is to be called exactly once, the result is not handled, and we are certain that the splitting is thread-safe.
%% Nov 15: next paragraph is right here, so no need to point
% (more on this in the next paragraph).

\lstinputlisting[caption={Add and maintain backlinks in {\hj}.},label=Listing:hyperback,float=\fl]{examples/hj/backlink/Source.java}

The before method \java{associateBefore} just stores (\Line{hyperback}{mtb}) the size of the vector in an instance variable, so that it is available in \java{associateAfter} method.  
This adds a small but non-zero risk of race-conditions in multi-threaded code, as a second thread could overwrite this variable before \java{associateAfter} has read it (on \Line{hyperback}{szrd}).  
%% Nov 15: not our place to discuss workarounds
%The most straight-forward way to protect against this would be to use the current thread object as a key into a \type{Hashtable} where per-thread instance variables are stored. 
%Additionally, we ought to protect against recursive invocation by keeping a stack of instance variables.
%% Nov 15: replaced with:
Similarly, recursive invocations need special care so no to overwrite the enclosing invocation's scope.

The signature of the method advised by this simulated ``around'' is constrained in solution as well, but in this case it is constrained by a cast in the after method body (\Line{hyperback}{cast}), trading off static safety against some runtime flexibility.  
%% nov 15: everyone knows it's toy code. NEVER make excuses for your examples.
%We open ourselves up to a runtime error by not checking the cast first, but as this is a simple example and we know how this code is going to be composed, we feel this is excused.

Unfortunately, we are reduced to comments to indicate that \java{targets}
is not implemented in this concern, as the techniques {\hj} uses to
identify deferred members work only for methods.

Peeking ahead, we foresee that two methods \java{associateBefore}
and \java{associateAfter} being composed as \keywrd{before} and
\keywrd{after} brackets to \java{addItem}.  The \java{margs} argument
(\Line{hyperback}{mta}) will be constructed by the HyperModule to pass
in the arguments from the bracketed method.

% -----------------------------
% -----------------------------

\sssect{The Adapter hypermodule in {\hj}}

As in the {\aj} solution, there is a mismatch between the
interfaces of the \collab{backlink} and \collab{caching} packages.
\Listing{hyperadapt} illustrates how these can be resolved.  Notice
however, that the deferred method \java{getContainer} is implemented
to throw \type{UnimplementedError} (\Line{hyperadapt}{getContThrow})
rather than being abstract. Had it been abstract, then class \type{Item}
would also have been abstract (\Line{hyperadapt}{absItem}), which in
turn would have forced \java{Container} (\Line{hyperadapt}{absCont})
to be abstract as well.

\lstinputlisting[caption={Adapting the Concerns in {\hj}.},label=Listing:hyperadapt,float=\fl]{examples/hj/adapt/Item.java}

% -----------------------------
% -----------------------------


\sssect{HyperSlice composition}

\Listing{hyperattach} shows the {\hj} specification for identifying
and composing the HyperSlices  we presented above.  The specification
consists of three parts that optionally can go into separate files.  The
\keywrd{hyperspace} specification (\Lines{hyperattach}{opt-hsb}{opt-hse})
identifies which classes are participating the the composition.
These classes are partitioned into hyperslices by the  \keywrd{concerns}
specification (\Lines{hyperattach}{opt-cmb}{opt-cme}).  Finally, the
\keywrd{hypermodule} (\Lines{hyperattach}{opt-hmb}{opt-hme}) chooses
which of these hyperslices to compose, and how their contents relate.

\begin{figure*}[tb] 
\begin{lstlisting}[caption={Attach the slices in {\hj}.},mathescape=true,frame=,label=Listing:hyperattach]{}
\end{lstlisting}
\begin{tabular}{l|r} \hline \begin{minipage}[t]{.33\linewidth} 
  \lstinputlisting[keywords={with,additionally,ArgumentArray,variable,operation,hyperspace,composable,concerns,hypermodules,hypermodule,hyperslices,relationships,mergeByName,equate,into,forward,to,bracket,after,verbose,class,end,compose,before},frame=]{examples/hj/attach.optfake1}
\end{minipage} & \begin{minipage}[t]{.63\linewidth}
  \lstinputlisting[firstlabel=\thelstlabel,keywords={with,additionally,ArgumentArray,variable,operation,hyperspace,composable,concerns,hypermodules,hypermodule,hyperslices,relationships,mergeByName,equate,into,forward,to,bracket,after,verbose,class,end,compose,before},frame=]{examples/hj/attach.optfake2}
\end{minipage} \\ \hline \end{tabular} 
\end{figure*}

The \keywrd{relationships} clause has indentation for easier reading, but
is actually a sequence of flat declarations.  The \keywrd{mergeByName}
declaration is used mainly at the class level in this example,
automatically composing the similarly named classes (for example
\type{adapt.Container} and \type{base.Container}).  The result of the
composition of hyperslices is the union of all their classes, minus the
classes that have been composed, either through explicit annotations or
implicit by-name merging.  The situation at the level of class members
is analogous.

%% Nov 15: removed encapsulation niggle #3 

\johan{forward isn't released yet, and may be wrong. Peri is helping}

\Sssect{Summary}{hj-summary}

We note that we had to foresee the exact signature of \java{weight}, as
\java{oldcachedmethod} and \java{newcachedmethod} are required to have
the same signature in order to be able to replace the original method,
which impacts how often we are able to reuse the caching behavior.

Method bracketing---{\hj}'s approach to behavioral extension---has
a less severe version of the same problem.  We need access to the
receiver of the bracketed method in \java{associateAfter}, which is
passed in via an \type{Object} array, also containing any arguments
to the call.  Elements from this array are downcast to their concrete
types before use.  Unfortunately, what these types are assumed to be
is not apparent from the signature of the bracketing method, so {\hj}
has no way of statically determining whether a bracketing method is
typesafe with respect to the bracketed method.

%-----


%% Nov 15: 
%% merges the three locations where we discussed 
%% lack of encapsulation: very little editing, just textual merge

Lastly, we note that {\hj} offers no support for encapsulation, or to assert that a composed slice conforms to some interface: the set of visible classes and members in a composed slice is exactly the union of the constituent slices, modulo merging and explicit renaming.
It is thus complicated to update a slice's implementation without affecting its interface, which will make it impossible to perform local maintenance without possibly affecting the composed application, and difficult to predict the interface of a hypermodule without running the {\hj} tool.
  
A HyperSlice can be defined as a slice of a composed hypermodule, which in turn could be composed from slices, creating an import chain of arbitrarily length.  
The lack of encapsulation means that we must start at the sources and mentally propagate through the whole chain to build up the final interface, rather than having it declared as part of the hypermodule.  
The two effects also interact, in that adding a method to a module early in the chain can lead to a spurious match later on, with unintended effects.  
The situation is similar to that of accidental inheritance \Cite{meyer:book-88} or accidental method capture~\Cite{Mez:MainConst}.

%There is a side effect of the way {\hj} composes modules.  
%It implies that hypermodules lack encapsulation, as there is no way to avoid exporting every member and class in a slice.  
It \emph{is} possible to rename members and classes, thereby implementing a naming convention to indicate which module contents should not be externally visible, and minimizing unintended name clashes.
%However, this does not stop accidental name matches from invoking the \keywrd{mergeByName} rule, with unintended effects.



\revC{
On page 22, last sentence just before ssect D, the accidental method capture problem is attributed as a negative on the Hyper/J solution. It is not apparent to me, however, how the AC solution avoids this. For example, the match/role notation in Listing 5 also seems subject to this problem (that is, it may match to some unintended methods). Please explain why this problem is solved by AC - it is presented as not being a problem in AC, but exists with the other techniques.
}
\johan{Ok, we need to mention something about how explicit exports save us. As a req: we want to be able to control precisely what the interface of a module is. Notice that {\ji} gets this wrong too}

%********************************************************************************************
%********************************************************************************************

