Hello all,

(I'm a little new to the code base so please excuse me if what I'm bringing
up makes no sense)

I believe there is something wrong (or at least it is causing me problems)
with the AbstractMatcher#replaceParameters method in
struts/core/src/main/java/com/opensymphony/xwork2/config/impl/AbstractMatcher.java
(currently lines 153-170).  As the function currently works it will return
a map that has more keys than the "orig" map that is passed into it.  For
example, assume that I have the following config defined in my struts.xml
file:

<package name="test" namespace="/test">
  <action name="{paramOne}/{paramTwo} class="org.MyActionClass"
method="execute">
    <result name="success" type="stream">
      <param name="inputName">random</param>
    </result>
  </action>
</package>

If you send a request to "/test/uno/dos", this will trigger code in
ActionConfigMatcher (lines 95-103) that will construct the ResultConfig
objects to be used later on.  At one point you are going to be making a
call to AbstractMatcher#replaceParameters with something that looks like
the following:

orig:
  "inputName" -> "random"

vars:
  "0" -> "uno/dos"
  "paramOne" -> "uno"
  "1" -> "uno"
  "paramTwo" -> "dos"
  "2" -> "dos"

The result of this will be a map that looks like:
  "inputName" -> "random"
  "paramOne" -> "uno"
  "paramTwo" -> "dos"

What I don't understand is why "paramOne" and "paramTwo" are now in the
map.  It seems to me that this method should just replacing keys and values
that have placeholders with whatever they are holding their place for.
What I have no idea about though is if changing this will cause something
to break that relies on this logic.  Or maybe I'm missing something for how
this method is supposed to function?

For the most part this error is pretty silent however I did come across a
situation where this was causing a problem.  The problem is that later on
in the code when we are constructing the result, if you are using the
StrutsResultFactory you will end up in the setParameters method (line 65).
Here you will try to set the parameter on the Result object for ever
parameter that was defined in the resultConfig.  However the result config
will now contain all of the parameters of the action url (so in my example
above "paramOne" and "paramTwo").  These aren't actually parameters of a
StreamResult, so you'll get an exception when trying to set them that will
be caught by the try block on line 71.  However we ran into a performance
problem as we had a spike of 100 requests to one action that had 8
parameters.  Creating the exception goes through
com/opensymphony/xwork2/util/location/LocationUtils.java the getLocation
method. This ends up calling a ClassLoader 4 separate times.  Thus in the
end you have 100 * 8 * 4 calls to this same ClassLoader which causes each
of these calls to bottleneck.

I'm willing to work on helping to fix, but I wanted to get confirmation
that I was understanding what was happening correctly rather than just
mis-interpretting what the method is supposed to do before I started on
anything or filed a JIRA issue.  Let me know what others think.

Thanks,
Alex K

Reply via email to