List Info

Thread: MethodAccessException in emitted code "GetImplementation"




MethodAccessException in emitted code "GetImplementation"
user name
2006-10-20 16:35:19
I too have encountered a very similar issue, though with the
corresponding "Set" version of
DelegatePropertyGetAccessor. From what I
could tell, there appears to be a limitation in current
ibatis where
domain objects are restricted from being generics or having
them as
properties, except for a few that are specifically or
transparently
supported by ibatis (e.g. IList<T>,
Nullable<T>).

Unfortunately, I've not had the time to dig into the ibatis
code
involved, so I have had to dumb down my domain model quite a
bit in
places where generics could have been used to great
advantage. That
"dumbing down" is now impacting complexity more
and more as I work my
way up through the layers of my application. :(

I'll present a small example here in case it is of help to
the ibatis
devs:

Given a domain model layer supertype called Entity, if I
attempt to map
via ibatis the data for another class called
Similarity<T> where T :
Entity, I will get the kind of exception Finn has described,
though for
me it was on the "Set" side when using
Similarity<T> in a result map.
This error also persisted even if I took the generic out of
the class's
explicit definition and instead referenced a class called
EntitySimilarity : Similarity<Entity>.

Jeremy


-----Original Message-----
From: Finn Nielsen [mailto:fn2177surfmail.dk] 
Sent: Friday, October 20, 2006 5:19 AM
To: user-csibatis.apache.org
Subject: MethodAccessException in emitted code
"GetImplementation"

Hi,
 
First of all, great work with iBATIS. 
 
Now, on to the subject. I am not sure if my observation is a
problem
with iBATIS, a feature request or a problem with my own
code. Therefore
I will start out by sending this mail.
 

An example of my environment (heavily abstracted):
.NET version 2.0.
 
iBATIS binaries:
IBatisNet.Common 1.4.1
IBatisNet.DataMapper 1.5.1
IBatisNet.DataAccess 1.8.1
 
I have a Common assembly which defines common utility types
for use
within the domain model. The utility types often use
generics. The
Common assembly is dependant on two other assemblies not
mentioned here,
but naturally only using public stuff in the dependant
assemblies.
One particular class is:
public class SpecialReference<T> where T : class
{
  // stuff omitted
 
  public T Value
  {
   get { /*...*/ }
   set { /*...*/ }
  }
}

I have a Model assembly which contains the domain model
types. Is
dependant on the Common assembly.
Two fictive domain model classes are:
public class DomainObjectA
{
  private int identifier;
  // stuff omitted
}


public class DomainObjectB
{
  private SpecialReference<DomainObjectA>
domainObjectA;
  // stuff omitted
}
 
In my mapping xml file for DomainObjectB I got stuff like:
<insert id="insertDomainObjectB"
parameterClass="DomainObjectB">
      INSERT INTO DOM_OBJ_B (columns) 
      VALUES (/* omitted stuff */,
#domainObjectA.Value.identifier#, /*
omitted stuff */)
</insert>
 
 
 
The symptom:
When I insert a DomainObjectB I get a MethodAccessException
where the
stack trace points to "GetImplementation". I know
that domainObjectA
within the DomainObjectB instance has been properly
initialized.
 
 
Analysis
I tried referencing the iBATIS source (Source Revision
426164) with
which I was able to reporduce the problem. The
MethodAccessException
occured in the emitted code within
IBatisNet.Common.Utilities.Objects.Members.DelegatePropertyG
etAccessor.
That is, when the emitted code was invoked using the
GetValue delegate.
The odd thing is, that I am sure that the
#specialDomainObjectA.Value.identifier#  is valid, in the
sence that the
SpecialReference<T> class is public, and so is the
Value property.
 
Next I tried in the IBatis.Common.2005 project to reference
the Model
and Common assemblies, and implement my own hardcoded
GetValue delegate
which was typed for DomainObjectB, but basically did the
same as the
emitted code. That is, cast the input object to the specific
type,
invoke the get property and return the result. This worked,
i.e. I got
no MethodAccessException. Afterwards I removed my own
experimentation
code from the iBATIS source and also removed the references
for the
assemblies Model and Common.
 
After a couple of other unsuccessfull attempts i found a
"cure". Within
IBatisNet.Common.Utilities.Objects.Members.DelegatePropertyG
etAccessor a
line of code states:
DynamicMethod dynamicMethod = new
DynamicMethod("GetImplementation",
typeof(object), new Type[] { typeof(object) },
this.GetType().Module,
false);
I flipped the last boolean to true, which means to skip JIT
visibility
checks on members of all the types in all modules. This
worked.
 

Question
Is the need for changing the boolean from false to true:
1. A flaw in the IBatisNet.Common assembly
(IBatisNet.Common.Utilities.Objects.Members.DelegateProperty
GetAccessor
and
IBatisNet.Common.Utilities.Objects.Members.DelegatePropertyS
etAccessor
classes).
2. A flaw in my code,
or
3. A feature request for IBatisNet.Common
 
 
Thanks for taking the time to read my mail. 
 
Kind regards
Finn Nielsen


[1]

about | contact  Other archives ( Real Estate discussion Medical topics )