cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Maurizio Pillitu <m.pill...@thebug.it>
Subject cocoon-javaflow in cocoon 2.2
Date Thu, 10 Aug 2006 21:25:27 GMT
Hi everybody,
me and Simone spent few days trying to obtain a working javaflow again in cocoon 2.2, and
to understand how it works deeply; we would like to report our achievements and problems.

We started trying to obtain a complete system (reloading, runtime instrumentation etc..).
But then scaled down step by step and arrived to the problem which is stopping us right now.

We are working with the flow class instrumented statically, as well as AbstractContinuable,
FormInstance and the Invoker.

The form shows up correctly, but when we submit the form, ClassCastException :

Caused by: java.lang.ClassCastException:
org.apache.cocoon.samples.flow.java.SimpleFlow
  at org.apache.cocoon.components.flow.java.Invoker.run(Invoker.java)
  at org.apache.commons.javaflow.bytecode.StackRecorder.execute(StackRecorder.java:95)
  at org.apache.commons.javaflow.Continuation.continueWith(Continuation.java:170)
  at org.apache.cocoon.components.flow.java.JavaInterpreter.handleContinuation(JavaInterpreter.java:182)
  at org.apache.cocoon.components.treeprocessor.sitemap.CallFunctionNode.invoke(CallFunctionNode.java:98)

When the form is rendered, the JavaInterprer instanciates an Invoker to pass to the Continuation
object; the Invoker is responsible to call the Javaflow method that has been passed by the
JavaInterpreter, using reflection. Since the class must be enhanced, also the method.invoke
instruction should be, but it seems that the BcelClassTransformer doesn't parse this case
(In this part we has serious difficulties to understand the code because we're not to deep
into the JVM bytecode specs and stuff like that).

In fact, if we replace the "method.invoke(o)" with "o.method()" (no reflection involved) it
works correctly.

IIUC the core of the instrumentation is done into the rewrite method, that parses the bytecode
operations and decides what to do; adding a
block that identifies the invoke operation and adds a method call would work; we tried unluckily
to implement it, maybe someone could help us to understand how to do it.

As I said, we arrived to this error by scaling down our target, our first test was to enhance
a simple Java class, out of cocoon environment, using the FilesystemAlterationMonitor, that
monitors a certain folder (in this case the folder containing the class file of the Javaflow)
and enhance it, if it has been changed. We found a ClassFormatException ( java.lang.ClassFormatError:
Incompatible magic value -272646673 in class file jci/Simple ) trying to read the original
bytecode of the class; debugging the code we discovered that the ReloadingListener is using
a FileReader to read the bytecode of the class; the FileReader parses the byte stream depending
on a certain char encoding. so the bytecode is not recognized by the classloader. Using a
FileInputStream it works (ReloadingClassLoaderTestCase confirms; with the original FileReader
implementation it fails).

Then we tried to integrate the FilesystemAlterationMonitor with the cocoon classloader configuration,
in order to automatically reload and enhance the Javaflows when changed, but we faced with
some problems.

- The FilesystemAlterationMonitor always notifies the changes of those classes that are enhanced;
the check is based on file.getLastModified() value, but every time the value is lower then
the last one, so the change notification is triggered. We didn't investigate more.

- The FileResourceStore fails trying to get the file by the filesystem:

private File getFile(final String pResourceName) {
  final String fileName = pResourceName.replace('/',File.separatorChar);
  return new File(root, fileName);
}

where pResourceName = "org.apache.cocoon.samples.flow.java.SimpleFlow"; changing the return
statement to :

return new File(root, 
  fileName.replace('.',File.separatorChar).concat(".class"));

it seems to work correctly.

Before send some patches we'd like to know if we're investigating in the right direction or
not.

We can also provide our temporary changes to the javaflow poms in order to enhance the JavaInterpreter
and the javaflow classes at build time, using the RewriteAntTask provided by commons-javaflow
and some fix to the cocoon-javaflow-sample block.

Regards,

  Maurizio and Simone


Mime
View raw message