You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openjpa.apache.org by Mark Struberg <st...@yahoo.de.INVALID> on 2023/04/30 15:19:25 UTC

Need someone for pair programming/rubberducking for low level stuff

Hi lords and ladies!

I'm right now in the process of moving openjpa to jakarta natively. 
While doing that I stumbled across a failing test (org.apache.openjpa.persistence.detach.TestDetachNoProxy#testClear10Compat) which is due to some proxy classes cannot be generated at build time.

I'm looking at the generated classes right now and I have to admit I'm a bit confused. 

It looks like they contain state? (via StateManager and delegating to super which is java.sql.Date)
public class java$sql$Date$proxy extends Date implements ProxyDate {
    private transient OpenJPAStateManager sm;
    private transient int field;

    public java$sql$Date$proxy(long var1) {
        super(var1);
    }

    public java$sql$Date$proxy(int var1, int var2, int var3) {
        super(var1, var2, var3);
    }

    public void setOwner(OpenJPAStateManager var1, int var2) {
        this.sm = var1;
        this.field = var2;
    }
    public void setDate(int var1) {
        Proxies.dirty(this, true);
        super.setDate(var1);
    }

    public void setMonth(int var1) {
        Proxies.dirty(this, true);
        super.setMonth(var1);
    }

But on the other hand we do cache those instances in ProxyManagerImpl

private ProxyDate getFactoryProxyDate(Class type) {
    // we don't lock here; ok if two proxies get generated for same type
    ProxyDate proxy = (ProxyDate) _proxies.get(type);
    if (proxy == null) {
        ClassLoader l = GeneratedClasses.getMostDerivedLoader(type,
            ProxyDate.class);
        Class pcls = loadBuildTimeProxy(type, l);
        if (pcls == null)
            pcls = GeneratedClasses.loadBCClass(
                generateProxyDateBytecode(type, true), l);
        proxy = (ProxyDate) instantiateProxy(pcls, null, null);
        _proxies.put(type, proxy);
    }
    return proxy;
}
and others.
It looks really weird, because this caches instances apparently? Reason why I do look at it is that with moving to Jakarta and Java11 the Serp stuff totally falls apart. And the ProxyManagerImpl#main which is called via Ant during the build to create a few proxies named java$sql$... in o.a.openjpa.util fails due to that.

And the build time proxies are serializable, while the dynamically built are NOT, because they are loaded via a separate synthetical BCClassLoader from Serp. Which is not available or gets ignored during deserialisation. Now we have org.apache.openjpa.persistence.detach.TestDetachNoProxy#testClear10Compat fail due to that if those proxy classes cannot be generated at build time. But likely this problem also appears in other cases where this mechanism is used. Which is _not_ really often the case afaict. Usually when enhancing the class the whole getter and setters are changed during enhancement to call StateManager#dirty.
Still it's imo important to fix the whole proxy generation.

Is anywhere around which has a spare hour (or a few) to help me look at this via a shared screen session? I fear this is not as easy as it looks like.

I'd first like to understand what this really is used for nowadays and only then replace it with an ASM based approach. Writing the ASM stuff is actually not the real problem here.

Anyone up for a hacking session?

txs and LieGrue,
strub



Re: Need someone for pair programming/rubberducking for low level stuff

Posted by Romain Manni-Bucau <rm...@gmail.com>.
Hi Mark,

Yes, I'm not sure I would have done it this way but it uses ProxyDate API
(and each type has its subtilities for the factory) and this one defines a
newInstance() which is used, depending the type by the statemanager
(org.apache.openjpa.kernel.StateManagerImpl#newFieldProxy for ex +
ProxyManagerImpl indeed) so it caches the factory which will create model
instances...but both are of the same type (guess it avoids to generate
multiple types but not sure why it is not public static too).

Guess the whole thing can totally rewritten while it keeps the tracking per
instance, even your idea to implement it in plain java works with the issue
to not support future java version if not done at runtime (new methods) but
guess it is okish.

Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://rmannibucau.metawerx.net/> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
<https://www.packtpub.com/application-development/java-ee-8-high-performance>


Le dim. 30 avr. 2023 à 19:26, Mark Struberg <st...@yahoo.de.invalid> a
écrit :

> Btw, I think I just found the reason for caching this instance. It seems
> they kind of folded together the factory and the actual proxy instances
> into the same class.
> The ProxyManagerImpl calls
> return proxy.newInstance();
> on this very proxy instance. And newInstance() is a method generated into
> each proxy which just calls new ThatProxyClass();
>
> So that makes sense it seems. I just wanted to understand what exactly
> goes on before I do change those things around in the bytecode ;)
>
>
> LieGrue,
> strub
>
>
>
> > Am 30.04.2023 um 19:13 schrieb Mark Struberg <struberg@yahoo.de.INVALID
> >:
> >
> > Hi Pawel!
> >
> > A few of your commits do look interesting. Will surely come back to it
> after getting rid of Serp!
> > I fear the problem I have now got introduced by finally wanting to get
> rid of generating Java5 code as due latest ASM does not support all
> features of ASM5 anymore.
> >
> > LieGrue,
> > strub
> >
> >
> >> Am 30.04.2023 um 18:18 schrieb Pawel Veselov <pa...@gmail.com>:
> >>
> >> FWIW, we did this on 3.1.2 to use in J17.
> >> https://github.com/veselov/openjpa/commits/3.1.2.xl4.j17
> >>
> >> On Sun, Apr 30, 2023 at 5:44 PM Mark Struberg <st...@yahoo.de.invalid>
> wrote:
> >>>
> >>> Oh btw, some work can be seen over here. Not yet ready to be pushed,
> but is maybe a start:
> >>>
> >>>
> >>>
> >>> https://github.com/struberg/openjpa/tree/jakartaee
> >>>
> >>>
> >>> LieGrue,
> >>> strub
> >>>
> >>>
> >>>> Am 30.04.2023 um 17:19 schrieb Mark Struberg
> <st...@yahoo.de.INVALID>:
> >>>>
> >>>> Hi lords and ladies!
> >>>>
> >>>> I'm right now in the process of moving openjpa to jakarta natively.
> >>>> While doing that I stumbled across a failing test
> (org.apache.openjpa.persistence.detach.TestDetachNoProxy#testClear10Compat)
> which is due to some proxy classes cannot be generated at build time.
> >>>>
> >>>> I'm looking at the generated classes right now and I have to admit
> I'm a bit confused.
> >>>>
> >>>> It looks like they contain state? (via StateManager and delegating to
> super which is java.sql.Date)
> >>>> public class java$sql$Date$proxy extends Date implements ProxyDate {
> >>>>  private transient OpenJPAStateManager sm;
> >>>>  private transient int field;
> >>>>
> >>>>  public java$sql$Date$proxy(long var1) {
> >>>>      super(var1);
> >>>>  }
> >>>>
> >>>>  public java$sql$Date$proxy(int var1, int var2, int var3) {
> >>>>      super(var1, var2, var3);
> >>>>  }
> >>>>
> >>>>  public void setOwner(OpenJPAStateManager var1, int var2) {
> >>>>      this.sm = var1;
> >>>>      this.field = var2;
> >>>>  }
> >>>>  public void setDate(int var1) {
> >>>>      Proxies.dirty(this, true);
> >>>>      super.setDate(var1);
> >>>>  }
> >>>>
> >>>>  public void setMonth(int var1) {
> >>>>      Proxies.dirty(this, true);
> >>>>      super.setMonth(var1);
> >>>>  }
> >>>>
> >>>> But on the other hand we do cache those instances in ProxyManagerImpl
> >>>>
> >>>> private ProxyDate getFactoryProxyDate(Class type) {
> >>>>  // we don't lock here; ok if two proxies get generated for same type
> >>>>  ProxyDate proxy = (ProxyDate) _proxies.get(type);
> >>>>  if (proxy == null) {
> >>>>      ClassLoader l = GeneratedClasses.getMostDerivedLoader(type,
> >>>>          ProxyDate.class);
> >>>>      Class pcls = loadBuildTimeProxy(type, l);
> >>>>      if (pcls == null)
> >>>>          pcls = GeneratedClasses.loadBCClass(
> >>>>              generateProxyDateBytecode(type, true), l);
> >>>>      proxy = (ProxyDate) instantiateProxy(pcls, null, null);
> >>>>      _proxies.put(type, proxy);
> >>>>  }
> >>>>  return proxy;
> >>>> }
> >>>> and others.
> >>>> It looks really weird, because this caches instances apparently?
> Reason why I do look at it is that with moving to Jakarta and Java11 the
> Serp stuff totally falls apart. And the ProxyManagerImpl#main which is
> called via Ant during the build to create a few proxies named java$sql$...
> in o.a.openjpa.util fails due to that.
> >>>>
> >>>> And the build time proxies are serializable, while the dynamically
> built are NOT, because they are loaded via a separate synthetical
> BCClassLoader from Serp. Which is not available or gets ignored during
> deserialisation. Now we have
> org.apache.openjpa.persistence.detach.TestDetachNoProxy#testClear10Compat
> fail due to that if those proxy classes cannot be generated at build time.
> But likely this problem also appears in other cases where this mechanism is
> used. Which is _not_ really often the case afaict. Usually when enhancing
> the class the whole getter and setters are changed during enhancement to
> call StateManager#dirty.
> >>>> Still it's imo important to fix the whole proxy generation.
> >>>>
> >>>> Is anywhere around which has a spare hour (or a few) to help me look
> at this via a shared screen session? I fear this is not as easy as it looks
> like.
> >>>>
> >>>> I'd first like to understand what this really is used for nowadays
> and only then replace it with an ASM based approach. Writing the ASM stuff
> is actually not the real problem here.
> >>>>
> >>>> Anyone up for a hacking session?
> >>>>
> >>>> txs and LieGrue,
> >>>> strub
> >>>>
> >>>>
> >>>
> >>
> >>
> >> --
> >> With best of best regards
> >> Pawel S. Veselov
> >
>
>

Re: Need someone for pair programming/rubberducking for low level stuff

Posted by Mark Struberg <st...@yahoo.de.INVALID>.
Btw, I think I just found the reason for caching this instance. It seems they kind of folded together the factory and the actual proxy instances into the same class.
The ProxyManagerImpl calls
return proxy.newInstance();
on this very proxy instance. And newInstance() is a method generated into each proxy which just calls new ThatProxyClass();

So that makes sense it seems. I just wanted to understand what exactly goes on before I do change those things around in the bytecode ;)


LieGrue,
strub



> Am 30.04.2023 um 19:13 schrieb Mark Struberg <st...@yahoo.de.INVALID>:
> 
> Hi Pawel!
> 
> A few of your commits do look interesting. Will surely come back to it after getting rid of Serp!
> I fear the problem I have now got introduced by finally wanting to get rid of generating Java5 code as due latest ASM does not support all features of ASM5 anymore.
> 
> LieGrue,
> strub
> 
> 
>> Am 30.04.2023 um 18:18 schrieb Pawel Veselov <pa...@gmail.com>:
>> 
>> FWIW, we did this on 3.1.2 to use in J17.
>> https://github.com/veselov/openjpa/commits/3.1.2.xl4.j17
>> 
>> On Sun, Apr 30, 2023 at 5:44 PM Mark Struberg <st...@yahoo.de.invalid> wrote:
>>> 
>>> Oh btw, some work can be seen over here. Not yet ready to be pushed, but is maybe a start:
>>> 
>>> 
>>> 
>>> https://github.com/struberg/openjpa/tree/jakartaee
>>> 
>>> 
>>> LieGrue,
>>> strub
>>> 
>>> 
>>>> Am 30.04.2023 um 17:19 schrieb Mark Struberg <st...@yahoo.de.INVALID>:
>>>> 
>>>> Hi lords and ladies!
>>>> 
>>>> I'm right now in the process of moving openjpa to jakarta natively.
>>>> While doing that I stumbled across a failing test (org.apache.openjpa.persistence.detach.TestDetachNoProxy#testClear10Compat) which is due to some proxy classes cannot be generated at build time.
>>>> 
>>>> I'm looking at the generated classes right now and I have to admit I'm a bit confused.
>>>> 
>>>> It looks like they contain state? (via StateManager and delegating to super which is java.sql.Date)
>>>> public class java$sql$Date$proxy extends Date implements ProxyDate {
>>>>  private transient OpenJPAStateManager sm;
>>>>  private transient int field;
>>>> 
>>>>  public java$sql$Date$proxy(long var1) {
>>>>      super(var1);
>>>>  }
>>>> 
>>>>  public java$sql$Date$proxy(int var1, int var2, int var3) {
>>>>      super(var1, var2, var3);
>>>>  }
>>>> 
>>>>  public void setOwner(OpenJPAStateManager var1, int var2) {
>>>>      this.sm = var1;
>>>>      this.field = var2;
>>>>  }
>>>>  public void setDate(int var1) {
>>>>      Proxies.dirty(this, true);
>>>>      super.setDate(var1);
>>>>  }
>>>> 
>>>>  public void setMonth(int var1) {
>>>>      Proxies.dirty(this, true);
>>>>      super.setMonth(var1);
>>>>  }
>>>> 
>>>> But on the other hand we do cache those instances in ProxyManagerImpl
>>>> 
>>>> private ProxyDate getFactoryProxyDate(Class type) {
>>>>  // we don't lock here; ok if two proxies get generated for same type
>>>>  ProxyDate proxy = (ProxyDate) _proxies.get(type);
>>>>  if (proxy == null) {
>>>>      ClassLoader l = GeneratedClasses.getMostDerivedLoader(type,
>>>>          ProxyDate.class);
>>>>      Class pcls = loadBuildTimeProxy(type, l);
>>>>      if (pcls == null)
>>>>          pcls = GeneratedClasses.loadBCClass(
>>>>              generateProxyDateBytecode(type, true), l);
>>>>      proxy = (ProxyDate) instantiateProxy(pcls, null, null);
>>>>      _proxies.put(type, proxy);
>>>>  }
>>>>  return proxy;
>>>> }
>>>> and others.
>>>> It looks really weird, because this caches instances apparently? Reason why I do look at it is that with moving to Jakarta and Java11 the Serp stuff totally falls apart. And the ProxyManagerImpl#main which is called via Ant during the build to create a few proxies named java$sql$... in o.a.openjpa.util fails due to that.
>>>> 
>>>> And the build time proxies are serializable, while the dynamically built are NOT, because they are loaded via a separate synthetical BCClassLoader from Serp. Which is not available or gets ignored during deserialisation. Now we have org.apache.openjpa.persistence.detach.TestDetachNoProxy#testClear10Compat fail due to that if those proxy classes cannot be generated at build time. But likely this problem also appears in other cases where this mechanism is used. Which is _not_ really often the case afaict. Usually when enhancing the class the whole getter and setters are changed during enhancement to call StateManager#dirty.
>>>> Still it's imo important to fix the whole proxy generation.
>>>> 
>>>> Is anywhere around which has a spare hour (or a few) to help me look at this via a shared screen session? I fear this is not as easy as it looks like.
>>>> 
>>>> I'd first like to understand what this really is used for nowadays and only then replace it with an ASM based approach. Writing the ASM stuff is actually not the real problem here.
>>>> 
>>>> Anyone up for a hacking session?
>>>> 
>>>> txs and LieGrue,
>>>> strub
>>>> 
>>>> 
>>> 
>> 
>> 
>> -- 
>> With best of best regards
>> Pawel S. Veselov
> 


Re: Need someone for pair programming/rubberducking for low level stuff

Posted by Mark Struberg <st...@yahoo.de.INVALID>.
Hi Pawel!

A few of your commits do look interesting. Will surely come back to it after getting rid of Serp!
I fear the problem I have now got introduced by finally wanting to get rid of generating Java5 code as due latest ASM does not support all features of ASM5 anymore.

LieGrue,
strub


> Am 30.04.2023 um 18:18 schrieb Pawel Veselov <pa...@gmail.com>:
> 
> FWIW, we did this on 3.1.2 to use in J17.
> https://github.com/veselov/openjpa/commits/3.1.2.xl4.j17
> 
> On Sun, Apr 30, 2023 at 5:44 PM Mark Struberg <st...@yahoo.de.invalid> wrote:
>> 
>> Oh btw, some work can be seen over here. Not yet ready to be pushed, but is maybe a start:
>> 
>> 
>> 
>> https://github.com/struberg/openjpa/tree/jakartaee
>> 
>> 
>> LieGrue,
>> strub
>> 
>> 
>>> Am 30.04.2023 um 17:19 schrieb Mark Struberg <st...@yahoo.de.INVALID>:
>>> 
>>> Hi lords and ladies!
>>> 
>>> I'm right now in the process of moving openjpa to jakarta natively.
>>> While doing that I stumbled across a failing test (org.apache.openjpa.persistence.detach.TestDetachNoProxy#testClear10Compat) which is due to some proxy classes cannot be generated at build time.
>>> 
>>> I'm looking at the generated classes right now and I have to admit I'm a bit confused.
>>> 
>>> It looks like they contain state? (via StateManager and delegating to super which is java.sql.Date)
>>> public class java$sql$Date$proxy extends Date implements ProxyDate {
>>>   private transient OpenJPAStateManager sm;
>>>   private transient int field;
>>> 
>>>   public java$sql$Date$proxy(long var1) {
>>>       super(var1);
>>>   }
>>> 
>>>   public java$sql$Date$proxy(int var1, int var2, int var3) {
>>>       super(var1, var2, var3);
>>>   }
>>> 
>>>   public void setOwner(OpenJPAStateManager var1, int var2) {
>>>       this.sm = var1;
>>>       this.field = var2;
>>>   }
>>>   public void setDate(int var1) {
>>>       Proxies.dirty(this, true);
>>>       super.setDate(var1);
>>>   }
>>> 
>>>   public void setMonth(int var1) {
>>>       Proxies.dirty(this, true);
>>>       super.setMonth(var1);
>>>   }
>>> 
>>> But on the other hand we do cache those instances in ProxyManagerImpl
>>> 
>>> private ProxyDate getFactoryProxyDate(Class type) {
>>>   // we don't lock here; ok if two proxies get generated for same type
>>>   ProxyDate proxy = (ProxyDate) _proxies.get(type);
>>>   if (proxy == null) {
>>>       ClassLoader l = GeneratedClasses.getMostDerivedLoader(type,
>>>           ProxyDate.class);
>>>       Class pcls = loadBuildTimeProxy(type, l);
>>>       if (pcls == null)
>>>           pcls = GeneratedClasses.loadBCClass(
>>>               generateProxyDateBytecode(type, true), l);
>>>       proxy = (ProxyDate) instantiateProxy(pcls, null, null);
>>>       _proxies.put(type, proxy);
>>>   }
>>>   return proxy;
>>> }
>>> and others.
>>> It looks really weird, because this caches instances apparently? Reason why I do look at it is that with moving to Jakarta and Java11 the Serp stuff totally falls apart. And the ProxyManagerImpl#main which is called via Ant during the build to create a few proxies named java$sql$... in o.a.openjpa.util fails due to that.
>>> 
>>> And the build time proxies are serializable, while the dynamically built are NOT, because they are loaded via a separate synthetical BCClassLoader from Serp. Which is not available or gets ignored during deserialisation. Now we have org.apache.openjpa.persistence.detach.TestDetachNoProxy#testClear10Compat fail due to that if those proxy classes cannot be generated at build time. But likely this problem also appears in other cases where this mechanism is used. Which is _not_ really often the case afaict. Usually when enhancing the class the whole getter and setters are changed during enhancement to call StateManager#dirty.
>>> Still it's imo important to fix the whole proxy generation.
>>> 
>>> Is anywhere around which has a spare hour (or a few) to help me look at this via a shared screen session? I fear this is not as easy as it looks like.
>>> 
>>> I'd first like to understand what this really is used for nowadays and only then replace it with an ASM based approach. Writing the ASM stuff is actually not the real problem here.
>>> 
>>> Anyone up for a hacking session?
>>> 
>>> txs and LieGrue,
>>> strub
>>> 
>>> 
>> 
> 
> 
> -- 
> With best of best regards
> Pawel S. Veselov


Re: Need someone for pair programming/rubberducking for low level stuff

Posted by Pawel Veselov <pa...@gmail.com>.
FWIW, we did this on 3.1.2 to use in J17.
https://github.com/veselov/openjpa/commits/3.1.2.xl4.j17

On Sun, Apr 30, 2023 at 5:44 PM Mark Struberg <st...@yahoo.de.invalid> wrote:
>
> Oh btw, some work can be seen over here. Not yet ready to be pushed, but is maybe a start:
>
>
>
> https://github.com/struberg/openjpa/tree/jakartaee
>
>
> LieGrue,
> strub
>
>
> > Am 30.04.2023 um 17:19 schrieb Mark Struberg <st...@yahoo.de.INVALID>:
> >
> > Hi lords and ladies!
> >
> > I'm right now in the process of moving openjpa to jakarta natively.
> > While doing that I stumbled across a failing test (org.apache.openjpa.persistence.detach.TestDetachNoProxy#testClear10Compat) which is due to some proxy classes cannot be generated at build time.
> >
> > I'm looking at the generated classes right now and I have to admit I'm a bit confused.
> >
> > It looks like they contain state? (via StateManager and delegating to super which is java.sql.Date)
> > public class java$sql$Date$proxy extends Date implements ProxyDate {
> >    private transient OpenJPAStateManager sm;
> >    private transient int field;
> >
> >    public java$sql$Date$proxy(long var1) {
> >        super(var1);
> >    }
> >
> >    public java$sql$Date$proxy(int var1, int var2, int var3) {
> >        super(var1, var2, var3);
> >    }
> >
> >    public void setOwner(OpenJPAStateManager var1, int var2) {
> >        this.sm = var1;
> >        this.field = var2;
> >    }
> >    public void setDate(int var1) {
> >        Proxies.dirty(this, true);
> >        super.setDate(var1);
> >    }
> >
> >    public void setMonth(int var1) {
> >        Proxies.dirty(this, true);
> >        super.setMonth(var1);
> >    }
> >
> > But on the other hand we do cache those instances in ProxyManagerImpl
> >
> > private ProxyDate getFactoryProxyDate(Class type) {
> >    // we don't lock here; ok if two proxies get generated for same type
> >    ProxyDate proxy = (ProxyDate) _proxies.get(type);
> >    if (proxy == null) {
> >        ClassLoader l = GeneratedClasses.getMostDerivedLoader(type,
> >            ProxyDate.class);
> >        Class pcls = loadBuildTimeProxy(type, l);
> >        if (pcls == null)
> >            pcls = GeneratedClasses.loadBCClass(
> >                generateProxyDateBytecode(type, true), l);
> >        proxy = (ProxyDate) instantiateProxy(pcls, null, null);
> >        _proxies.put(type, proxy);
> >    }
> >    return proxy;
> > }
> > and others.
> > It looks really weird, because this caches instances apparently? Reason why I do look at it is that with moving to Jakarta and Java11 the Serp stuff totally falls apart. And the ProxyManagerImpl#main which is called via Ant during the build to create a few proxies named java$sql$... in o.a.openjpa.util fails due to that.
> >
> > And the build time proxies are serializable, while the dynamically built are NOT, because they are loaded via a separate synthetical BCClassLoader from Serp. Which is not available or gets ignored during deserialisation. Now we have org.apache.openjpa.persistence.detach.TestDetachNoProxy#testClear10Compat fail due to that if those proxy classes cannot be generated at build time. But likely this problem also appears in other cases where this mechanism is used. Which is _not_ really often the case afaict. Usually when enhancing the class the whole getter and setters are changed during enhancement to call StateManager#dirty.
> > Still it's imo important to fix the whole proxy generation.
> >
> > Is anywhere around which has a spare hour (or a few) to help me look at this via a shared screen session? I fear this is not as easy as it looks like.
> >
> > I'd first like to understand what this really is used for nowadays and only then replace it with an ASM based approach. Writing the ASM stuff is actually not the real problem here.
> >
> > Anyone up for a hacking session?
> >
> > txs and LieGrue,
> > strub
> >
> >
>


-- 
With best of best regards
Pawel S. Veselov

Re: Need someone for pair programming/rubberducking for low level stuff

Posted by Mark Struberg <st...@yahoo.de.INVALID>.
Oh btw, some work can be seen over here. Not yet ready to be pushed, but is maybe a start:



https://github.com/struberg/openjpa/tree/jakartaee


LieGrue,
strub


> Am 30.04.2023 um 17:19 schrieb Mark Struberg <st...@yahoo.de.INVALID>:
> 
> Hi lords and ladies!
> 
> I'm right now in the process of moving openjpa to jakarta natively. 
> While doing that I stumbled across a failing test (org.apache.openjpa.persistence.detach.TestDetachNoProxy#testClear10Compat) which is due to some proxy classes cannot be generated at build time.
> 
> I'm looking at the generated classes right now and I have to admit I'm a bit confused. 
> 
> It looks like they contain state? (via StateManager and delegating to super which is java.sql.Date)
> public class java$sql$Date$proxy extends Date implements ProxyDate {
>    private transient OpenJPAStateManager sm;
>    private transient int field;
> 
>    public java$sql$Date$proxy(long var1) {
>        super(var1);
>    }
> 
>    public java$sql$Date$proxy(int var1, int var2, int var3) {
>        super(var1, var2, var3);
>    }
> 
>    public void setOwner(OpenJPAStateManager var1, int var2) {
>        this.sm = var1;
>        this.field = var2;
>    }
>    public void setDate(int var1) {
>        Proxies.dirty(this, true);
>        super.setDate(var1);
>    }
> 
>    public void setMonth(int var1) {
>        Proxies.dirty(this, true);
>        super.setMonth(var1);
>    }
> 
> But on the other hand we do cache those instances in ProxyManagerImpl
> 
> private ProxyDate getFactoryProxyDate(Class type) {
>    // we don't lock here; ok if two proxies get generated for same type
>    ProxyDate proxy = (ProxyDate) _proxies.get(type);
>    if (proxy == null) {
>        ClassLoader l = GeneratedClasses.getMostDerivedLoader(type,
>            ProxyDate.class);
>        Class pcls = loadBuildTimeProxy(type, l);
>        if (pcls == null)
>            pcls = GeneratedClasses.loadBCClass(
>                generateProxyDateBytecode(type, true), l);
>        proxy = (ProxyDate) instantiateProxy(pcls, null, null);
>        _proxies.put(type, proxy);
>    }
>    return proxy;
> }
> and others.
> It looks really weird, because this caches instances apparently? Reason why I do look at it is that with moving to Jakarta and Java11 the Serp stuff totally falls apart. And the ProxyManagerImpl#main which is called via Ant during the build to create a few proxies named java$sql$... in o.a.openjpa.util fails due to that.
> 
> And the build time proxies are serializable, while the dynamically built are NOT, because they are loaded via a separate synthetical BCClassLoader from Serp. Which is not available or gets ignored during deserialisation. Now we have org.apache.openjpa.persistence.detach.TestDetachNoProxy#testClear10Compat fail due to that if those proxy classes cannot be generated at build time. But likely this problem also appears in other cases where this mechanism is used. Which is _not_ really often the case afaict. Usually when enhancing the class the whole getter and setters are changed during enhancement to call StateManager#dirty.
> Still it's imo important to fix the whole proxy generation.
> 
> Is anywhere around which has a spare hour (or a few) to help me look at this via a shared screen session? I fear this is not as easy as it looks like.
> 
> I'd first like to understand what this really is used for nowadays and only then replace it with an ASM based approach. Writing the ASM stuff is actually not the real problem here.
> 
> Anyone up for a hacking session?
> 
> txs and LieGrue,
> strub
> 
>