ibatis-user-cs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Finn Nielsen <fn2...@surfmail.dk>
Subject MethodAccessException in emitted code "GetImplementation"
Date Fri, 20 Oct 2006 12:18:38 GMT
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
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 */)
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.
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.DelegatePropertyGetAccessor.
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.DelegatePropertyGetAccessor
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.

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

View raw message