Java Aspect Component FAQ

This FAQ lists a few general interest questions and a few common problems that you may encounter while using JAC. If your question is not listed here, do not hesitate to use the mailing lists to ask for some help.

General interest questions

Aspect-Oriented Programming

What is Aspect-Oriented Programming?

Aspect-Oriented Programming (AOP) is a programming paradigm and philosophy that improves Separation of concerns when developping complex softwares. JAC core provides an AOP technology and this is why JAC applications are very simple to develop and very maintanable. AOP also improves reusability of software components.

What is an Aspect Component?

An Aspect Component is a reusable technical unit in JAC. For instance, the persistence or the authentication in JAC are implemented whitin Aspect Components which are totally independant from the rest of the code. An Aspect Component can be dynamically added / removed (we say it is woven / unwoven).

Can I use only one aspect component for my application (e.g. persistence)?

This is possible. However, the real advantages of AOP comes when several concerns crosscut. For this reason, we strongly advice to program fully aspect-oriented applications.

What are the differences between JAC and AspectJ?

JAC is very similar to AspectJ in the employed programming concepts (pointcuts, advices (=wrapping methods), joinpoints).

The main differences come from the implementation that allows dynamic aspect weaving/unweaving (the aspects can be added/removed without compiling and stopping the application). Moreover, JAC is a framework so it does not defines a new langage or compiler (it can be used as regular Java, in any development environment).

The dynamic aspect weaving has a cost on performances which is due to the java.lang.reflect use. A joinpoint in JAC has an overhead that is similar to the reflection cost in Java (greatly optimized in java 1.4 but still slower than a regular call). Most of the time, this overhead is very neglectable compared to the aspects inherent overhead (e.g. a persistence aspect). However, it makes JAC not very suited to all the kind of AOSD. This pb will be overcome soon with static joinpoints (made through a compilation process).

Another main difference is that JAC comes with a set of ready-to-use aspect components. To reuse an aspect component, you just need to write a configuration program that is declarative (not far from a DSL). Thus the final user does not need to know anything about the actual aspect implementation.

Finally, JAC provides support for distributed pointcuts (pointcuts that can extend programs that are distributed on several JAC containers). This feature can be used to efficiently program distributed aspects such as fault-tolerance, data-consistency, load-balancing, or caching. All these can be useful for clusturing JAC containers.

Can you give me a brief overview on the differencies between JAC and AspectJ syntaxes?

The main difference regarding the programming is that AspectJ is a new language and that JAC is a framework.

Let us take a simple aspect:

*** AspectJ version ***

aspect Sample {

  pointcut setter() : target(Point) && 
      (call(void setX(int)) || call(void setY(int)));

  void around() : setter() {
     System.out.println("about to set something");
     proceed();
     System.out.println("something was set");       }
}
*** JAC version ***

class SampleAC extends AspectComponent {

   public SampleAC() {
       pointcut("ALL","Point",
                "setX(int):void || setY(int):void",
                new AWrapper(this), "printSomething");
   }

   public AWrapper extends Wrapper {
       public AWrapper(AspectComponent ac) { super(ac); }
       public void printSomething(Interaction interaction) {
          System.out.println("about to set something");
          proceed(interaction);
          System.out.println("something was set");            }
   }
}

But if you want to generically capture all the getters in your pointcut, one of the great advantages of JAC is that you can use generic keywords:

pointcut("ALL","Point","SETTERS", new AWrapper(), "printSomething");

This feature is possible because of the bytecode analysis of the classes performed at load-time. JAC implements an algorithm that detects which methods read or write fields, references or collections. This feature simplifies the programming of aspects and can be used to implement aspects such as caching aspects (MODIFIERS keyword), persistency, etc.

What is the overhead of bytecode analysis and dynamic weaving?

The bytecode analysis slows down the classes loading time by a 5 factor. However, JAC caches the result of the translation so that this overhead is only noticeable on the first program launch.

The dynamic aspect weaving has a cost on performances which is due to the java.lang.reflect use. A joinpoint in JAC has an overhead that is similar to the reflection cost in Java (greatly optimized in java 1.4 but still slower than a regular call). Most of the time, this overhead is very neglectable compared to the aspects inherent overhead (e.g. a persistence aspect). However, it makes JAC not very suited to all the kind of AOSD. This pb will be overcome soon with static joinpoints (made through a compilation process).

JAC and J2EE

Can JAC be regarded as an application server?

YES, YES, YES!! JAC is a very flexible container that can dynamically add technical services through aspects.

Is JAC J2EE compliant?

The answer is NO! JAC implements its own standards for the moment. Some parts of J2EE implementations could be reused in the future but most of them will simply not fit. In fact, the JAC Aspect-Oriented technology implements generalized and improved separation of concerns compared to J2EE.

What is a POJO?

JAC components are not EJBs, they are POJOs (Plain Old Java Objects). A POJO is a component that does not implement any specific interface (on contrary to EJBs that must fullfill specific features to run on a J2EE container). With AOP, it is easy to make componants POJOs because it is the aspects that automatically and dynamically extends the objects to make them run on the JAC container.

Does JAC implement JDO?

JAC does not implement JDO since JDO is a particular implementation of a persistence aspect. In JAC, we use a JAC-based persistency aspect that can be compared to JDO in many ways except that it enters into an Aspect-Oriented logic and standardization. Thus, our persistence aspect is fully compliant with other JAC aspects.

Several JDO implementation pieces could be reused whithin our persistence aspect such as an O/R mapping or a query engine. For the moment, our implementation is simple, but greatly deals with references and collections (this is easy with aspects:).

Can JAC be interfaced whith non-JAC clients?

JAC can be accessed via RMI using the org.objectweb.jac.core.dist API. However, we encourage developpers to implement full-JAC applications since the benefits of aspects can also be seen at client-side. For instance, at client-side, you can use the GUI aspect, the remote-access aspect (to invoke servers), caching aspect (for performance) and local persistence aspect. Programming distributed applications is not well documented but you can ask for support about it. Anyway, it will be improved in the future.

Does JAC supports WEB developments? Can we use JSP with JAC?

JAC generates GUI with the GUI aspect (like any technical concern). JAC distribution includes Jetty so that JAC GUIs can be either Swing or WEB. JSP can be used to access JAC containers but, once again, you lose the benefits of the "all is aspect" philosophy.

Web issues

Can JAC be used with Apache?

Yes, you if you have a site rnning with Apache, you can keep it and just tell Apache to redirect some requests to JAC. Here's how to do it (tested with Apache 1.3).

  1. You must have the proxy and rewrite modules enabled in httpd.conf:
    LoadModule rewrite_module /usr/lib/apache/1.3/mod_rewrite.so
    LoadModule proxy_module /usr/lib/apache/1.3/mod_proxy.so
    
  2. Add a rewrite rule like this:
    RewriteEngine on
    RewriteRule ^/org/objectweb/jac/(.*) http://localhost:8088/org/objectweb/jac/$1 [P]
    

Licence

The GPL is known as "infectious". Do I have to distribute my own programs and aspects under the GPL ?

No. These are not considered derivative works. This is explicitly stated at the beginning of the LICENCE file. Moreover, JAC is now distributed under the LGPL.

Technical problems and issues

Misc.

java.lang.IllegalAccessException

If you get a java.lang.IllegalAccessException such as the following one, it probably means that you have a non public class <myPackage.myClass>.

java.lang.IllegalAccessException: <myPackage.myClass>
        at java.lang.Class.newInstance0(Native Method)
        at java.lang.Class.newInstance(Class.java:237)
        at org.objectweb.jac.aspects.gui.InputWrapper.askForParameters(InputWrapper.java:88)
        at java.lang.reflect.Method.invoke(Native Method)
        at org.objectweb.jac.core.Wrapping.nextWrapper(Wrapping.java:968)
        at org.objectweb.jac.core.Wrapping.nextWrapper(Wrapping.java:842)
        at shoubiao.PhotoRepository.addPhoto(PhotoRepository.java)
        at java.lang.reflect.Method.invoke(Native Method)
        at org.objectweb.jac.core.rtti.MethodItem.invoke(MethodItem.java:441)
        at org.objectweb.jac.core.InvokeThread.run(InvokeThread.java:200)

Parser error in acc file

Some aspect configuration file gives a parser error like that:

Syntax error
Couldn't repair and continue parse
ERROR: user.acc:1
ERROR: Parser error in user.acc : java.lang.Exception: Can't recover from previous error(s)
--- configuring session aspect ---

And the line of the error looks fine:

setUserClass calcul.Person email password profile;

Aspects define block keywords that can be used to group configuration items in .acc files. profile is one of them and is defined by the user aspect. If you want to use such a word not as a keyword, you must enclose it between double quotes:

setUserClass calcul.Person email password "profile";

java.net.SocketException: Broken pipe with postgresql

If you get a stack trace which looks like the following, it's likely that you restarted the postgresql server, so all the connections JAC had with it are broken. The solution is to restart the JAC server.

java.net.SocketException: Broken pipe
        at java.net.SocketOutputStream.socketWrite0(Native Method)
        at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
        at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:69)
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:127)
        at org.postgresql.PG_Stream.flush(PG_Stream.java:352)
        at org.postgresql.core.QueryExecutor.sendQuery(QueryExecutor.java:154)
        at org.postgresql.core.QueryExecutor.execute(QueryExecutor.java:70)
        at org.postgresql.jdbc1.AbstractJdbc1Connection.ExecSQL(AbstractJdbc1Connection.java:505)
        at org.postgresql.jdbc1.AbstractJdbc1Statement.execute(AbstractJdbc1Statement.java:320)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:48)
        at org.postgresql.jdbc1.AbstractJdbc1Statement.executeQuery(AbstractJdbc1Statement.java:153)
        at org.postgresql.jdbc1.AbstractJdbc1Statement.executeQuery(AbstractJdbc1Statement.java:141)
        at org.objectweb.jac.aspects.persistence.SQLStorage.executeQuery(SQLStorage.java:109)

Distribution

java.lang.ClassNotFoundException: org.objectweb.jac.core.dist.rmi.RMIRemoteContainer_Stub

rmiregistry's CLASSPATH is probably wrong. You should kill all rmiregistry processes and try again. You may also try to rebuild all classes.

RMI does not manage to resolve hosts under Linux

Because of the way rmi works, you should not have "127.0.0.1 <your_local_hostname>" in /etc/hosts

NoClassDefFoundError: org/objectweb/jac/core/dist/DistdClassLoader at org.objectweb.jac.core.dist.Distd.<init>

Check that a .java.policy is properly configured.