We are re-creating lost source code. Of the over 200 classes and gsp files only
3 files have given us any trouble.
2 of the files have an extra static class reference variable which is not used.
The most concerning issue is a missing Reference wrapper around a variable
called user.
The production source decompiles as such:
32 public Object doCall(Object it)
33 {
34 CallSite acallsite[];
35 Object user;
36 acallsite = $getCallSiteArray();
37 user = new
Reference(acallsite[0].call(acallsite[1].callGroovyObjectGetProperty(this),
acallsite[2].callGetProperty(acallsite[3].callGroovyObjectGetProperty(thi
s)),
acallsite[4].callGetProperty(acallsite[5].callGroovyObjectGetProperty(this)),
acallsite[6].callGetProperty(acallsite[7].callGroovyObjectGetProperty(this))));
38 if(!DefaultTypeTransformation.booleanUnbox(((Reference)
(user)).get()))
39 return acallsite[8].callCurrent(this,
ScriptBytecodeAdapter.createMap(new Object[] {
40 "controller", "errors", "action",
"userReportSessionExpired"
41 }));
42 acallsite[9].callCurrent(this,
acallsite[10].callGroovyObjectGetProperty(this));
43 acallsite[11];
44 JVM INSTR swap ;
45 JVM INSTR dup_x1 ;
46 new Integer(0);
47 call();
48 Object startDate;
49 startDate;
50 acallsite[12];
51 JVM INSTR swap ;
52 JVM INSTR dup_x1 ;
53 new Integer(1);
54 call();
55 Object endDate;
56 endDate;
57 JVM INSTR pop ;
58 Object responses = acallsite[13].callCurrent(this,
((Reference) (user)).get(), startDate, endDate,
acallsite[14].callGroovyObjectGetProperty(this));
59 Object summary =
acallsite[15].call(acallsite[16].callGroovyObjectGetProperty(this),
((Reference) (user)).get(), startDate, endDate);
60 return ScriptBytecodeAdapter.createMap(new Object[] {
61 "user", ((Reference) (user)).get(), "responses",
responses, "summary", summary
62 });
63 }
Looking at line 37 we can see user = new Reference(..., on some lines
inbetween, and finally on line 61 inside the map where it is used as a value
for key "user".
Later in the same file there is a very similar snippet of code, which again
uses Reference
136 public Object doCall(UserReportSearchCommand
userreportsearchcommand)
137 {
138 userreportsearchcommand;
139 JVM INSTR new #26 <Class Reference>;
140 JVM INSTR dup_x1 ;
141 JVM INSTR swap ;
142 Reference();
143 UserReportSearchCommand cmd;
144 cmd;
145 CallSite acallsite[] = $getCallSiteArray();
146 Object user = new
Reference(acallsite[0].call(acallsite[1].callGroovyObjectGetProperty(this),
acallsite[2].callGetProperty(acallsite[3].callGroovyObjectGetProperty(this)),
acallsite[4].callGetProperty(acallsite[5].callGroovyObjectGetProperty(this)),
acallsite[6].callGetProperty(acallsite[7].callGroovyObjectGetProperty(this))));
147 if(!DefaultTypeTransformation.booleanUnbox(((Reference)
(user)).get()))
148 {
149 return acallsite[8].callCurrent(this,
ScriptBytecodeAdapter.createMap(new Object[] {
150 "controller", "errors", "action",
"userReportSessionExpired"
151 }));
152 } else
153 {
154 Object responses = acallsite[9].callCurrent(this,
((Reference) (user)).get(),
acallsite[10].callGroovyObjectGetProperty(cmd.get()),
acallsite[11].callGroovyObjectGetProperty(cmd.get()),
acallsite[12].callGroovyObjectGetProperty(this));
155 return acallsite[13].callCurrent(this,
ScriptBytecodeAdapter.createMap(new Object[] {
156 "template", "responses", "model",
ScriptBytecodeAdapter.createMap(new Object[] {
157 "user", ((Reference) (user)).get(),
"responses", responses
158 })
159 }));
160 }
161 }
When we look at our atempted recovered source
def index =
{
//_closure1
//http://marc.info/?l=groovy-user&m=114378831527702 Why is this
not being wrapped in a Reference when prod.current does????
def user = userReportService.getAuthorizedUser(params.userId,
params.key, params.date)
if (!user)
{
return forward([controller: "errors", action:
"userReportSessionExpired"])
}
def (startDate, endDate) = initDates(params)
def responses = getPaginatedResponses(user, startDate, endDate,
params)
def summary = userReportService.getResponseSummary(user,
startDate, endDate)
return [user: user, responses: responses, summary: summary]
}
It generates very similar, but missing the Reference wrappers:
32 public Object doCall(UserReportSearchCommand cmd)
33 {
34 CallSite acallsite[];
35 Object user;
36 acallsite = $getCallSiteArray();
37 user =
acallsite[0].call(acallsite[1].callGroovyObjectGetProperty(this),
acallsite[2].callGetProperty(acallsite[3].callGroovyObjectGetProperty(this)),
acallsite[4].callGetProperty(acallsite[5].callGroovyObjectGetProperty(this)),
acallsite[6].callGetProperty(acallsite[7].callGroovyObjectGetProperty(this)));
38 if(!DefaultTypeTransformation.booleanUnbox(user))
39 return acallsite[8].callCurrent(this,
ScriptBytecodeAdapter.createMap(new Object[] {
40 "controller", "errors", "action",
"userReportSessionExpired"
41 }));
42 acallsite[9].callCurrent(this,
acallsite[10].callGroovyObjectGetProperty(this));
43 acallsite[11];
44 JVM INSTR swap ;
45 JVM INSTR dup_x1 ;
46 new Integer(0);
47 call();
48 Object startDate;
49 startDate;
50 acallsite[12];
51 JVM INSTR swap ;
52 JVM INSTR dup_x1 ;
53 new Integer(1);
54 call();
55 Object endDate;
56 endDate;
57 JVM INSTR pop ;
58 Object responses = acallsite[13].callCurrent(this, user,
startDate, endDate, acallsite[14].callGroovyObjectGetProperty(this));
59 Object summary =
acallsite[15].call(acallsite[16].callGroovyObjectGetProperty(this), user,
startDate, endDate);
60 return ScriptBytecodeAdapter.createMap(new Object[] {
61 "user", user, "responses", responses, "summary", summary
62 });
63 }
As we can see the decompiled code from the newly re-created code is almost
identical, sans the 5 Reference wrappers.
Looking at the next closure:
def updateResponses =
{ UserReportSearchCommand cmd ->
//_closure2
def user = userReportService.getAuthorizedUser(params.userId,
params.key, params.date)
if (!user)
{
return forward([controller: "errors", action:
"userReportSessionExpired"])
}
else
{
def responses = getPaginatedResponses(user,
cmd.startDate, cmd.endDate, params)
return render([template:"responses", model:[user: user,
responses: responses]])
}
}
The decompiled new code is *identical*
Why might the user variable be using a Reference in the old production code?
v/r,
Jason Pyeron