views:

508

answers:

1

Currently I'm trying to create sample Wicket page with Clojure (in existing wicket project). Code looks like this:

(ns a.set.of.packages.dataview.info.EmptyNodeInfo2Panel
  (:import [a.set.of.packages.tree TreeModelBean]
           [a.set.of.packages.dataview.supplemental GenericHeaderPanel]))  

(gen-class
  :name a.set.of.packages.dataview.info.EmptyNodeInfo2Panel
  :extends org.apache.wicket.markup.html.panel.Panel
  :state state
  :init init
  :constructors {[String a.set.of.packages.tree.TreeModelBean] [String]}
  :post-init construct)

(defn -init [id model-bean]
  [[id] nil])

(defn -construct [this id model-bean]
   (.add this (GenericHeaderPanel. "header" model-bean)))

When page being created I get following runtime error:

java.lang.IllegalArgumentException: No matching method found: add for class a.set.of.packages.dataview.info.EmptyNodeInfo2Panel

i.e. I can't call to the superclass methods.

Decompiled construct method looks like this:

public Object invoke(Object this, Object id, Object model_bean)
    throws Exception
{
    this = null;
    id = null;
    model_bean = null;
    return Reflector.invokeInstanceMethod(this, "add", new Object[] {
        new GenericHeaderPanel((String)"header", (TreeModelBean)model_bean)
    });
}

Where everything is set to null! Is this problem with constructor parameters mapping, incorrect decompilation or a bug?

+1  A: 

I've dug in Clojure internals and found root of the problem. Marked row doesn't work.

// clojure.lang.Reflector
static public boolean paramArgTypeMatch(Class paramType, Class argType)
{
  ...
    if(paramType == argType || paramType.isAssignableFrom(argType)) // <<<
    return true;
  ...

Probably there is class loader problem (I create EmptyNodeInfo2Panel class dynamically with Class.forName).

Classes that was matched are:

a.set.of.packages.dataview.supplemental.GenericHeaderPanel
org.apache.wicket.Component;

Interesting thing: when I print org.apache.wicket.Component class name from servlet respnose processing thread it prints as is, but when I print it from Reflector thead (through paramType.getName()), it prints in following form: [Lorg.apache.wicket.Component. I use Tomcat 5.5, are there any clues possible?

Andrew
"it prints in following form: `[Lorg.apache.wicket.Component`"The opening square bracket indicates an array of the class that follows.
pmf
Yes, I just figured it, and following construct method works: (defn -construct [this id model-bean] (.add this (into-array [(GenericHeaderPanel. "header" model-bean)]))I unattentive read Wicket docs on `add` method of Panel class. It takes variable arguments... I had crazy day :)
Andrew