You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by tomask79 <to...@embedit.cz> on 2018/04/18 08:10:55 UTC

Wicket's LazyInitProxyFactory runs incorrectly at WebLogic...

Hi guys,

this is the continuation of 

http://apache-wicket.1842946.n4.nabble.com/SpringBean-inside-WebSession-td4680162.html

We have found the root cause:

Is somehow possible to replace LazyInitProxyFactory.ProxyReplacement with
custom implementation?

Why I need that? I need following code tweak:

static class ProxyReplacement implements IClusterable {
        private static final long serialVersionUID = 1L;
        private final IProxyTargetLocator locator;
        private final String type;

        public ProxyReplacement(String type, IProxyTargetLocator locator) {
            this.type = type;
            this.locator = locator;
        }

        private Object readResolve() throws ObjectStreamException {
            Class<?> clazz = WicketObjects.resolveClass(this.type);
            if (clazz == null) {
                clazz = Class.forName(type, false,
this.getClass().getClassLoader());
                if (clazz == null) {
                     ClassNotFoundException cause = new
ClassNotFoundException("Could not resolve type [" 
                     + this.type + "] with the currently configured 
                      org.apache.wicket.application.IClassResolver");
                       throw new WicketRuntimeException(cause);
               }
            } else {
                return LazyInitProxyFactory.createProxy(clazz,
this.locator);
            }
        }
    }

Reason: 

WicketObject.resolveClass is incorrect:

public static <T> Class<T> resolveClass(final String className)
	{
		Class<T> resolved = null;
		try
		{
			if (Application.exists())
			{
				resolved = (Class<T>)Application.get()
					.getApplicationSettings()
					.getClassResolver()
					.resolveClass(className);
			}

			if (resolved == null)
			{
				resolved = (Class<T>)Class.forName(className, false,
Thread.currentThread()
					.getContextClassLoader());
			}
		}
		catch (ClassNotFoundException cnfx)
		{
			log.warn("Could not resolve class [" + className + "]", cnfx);
		}
		return resolved;
	}

Thread.currentThread().getContextClassLoader() when replicating session at
WebLogic this sometimes returns non-application classloader which ends with
mentioned ClassNotFoundException.....Also "if (resolved == null)" part is
useless if first part throws Exception....

We use Wicket 6.21.

1) Either is possible to replace LazyInitProxyFactory with custom
implementation....
2) Or can you please put my suggested change of ProxyReplacement.readResolve
into some patched version of 6.21?







--
Sent from: http://apache-wicket.1842946.n4.nabble.com/Users-forum-f1842947.html

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Wicket's LazyInitProxyFactory runs incorrectly at WebLogic...

Posted by tomask79 <to...@embedit.cz>.
"I guess the difference is in handling situation when  Application.exists() 
== false "

Exactly, as Maxim said.

--
Sent from: http://apache-wicket.1842946.n4.nabble.com/Users-forum-f1842947.html

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Wicket's LazyInitProxyFactory runs incorrectly at WebLogic...

Posted by Maxim Solodovnik <so...@gmail.com>.
I guess the difference is in handling situation when  Application.exists()
== false

On Wed, Apr 18, 2018 at 3:24 PM, Martin Grigorov <mg...@apache.org>
wrote:

> Hi,
>
> On Wed, Apr 18, 2018 at 11:10 AM, tomask79 <to...@embedit.cz>
> wrote:
>
> > Hi guys,
> >
> > this is the continuation of
> >
> > http://apache-wicket.1842946.n4.nabble.com/SpringBean-
> > inside-WebSession-td4680162.html
> >
> > We have found the root cause:
> >
> > Is somehow possible to replace LazyInitProxyFactory.ProxyReplacement
> with
> > custom implementation?
> >
> > Why I need that? I need following code tweak:
> >
> > static class ProxyReplacement implements IClusterable {
> >         private static final long serialVersionUID = 1L;
> >         private final IProxyTargetLocator locator;
> >         private final String type;
> >
> >         public ProxyReplacement(String type, IProxyTargetLocator
> locator) {
> >             this.type = type;
> >             this.locator = locator;
> >         }
> >
> >         private Object readResolve() throws ObjectStreamException {
> >             Class<?> clazz = WicketObjects.resolveClass(this.type);
> >             if (clazz == null) {
> >                 clazz = Class.forName(type, false,
> > this.getClass().getClassLoader());
> >                 if (clazz == null) {
> >                      ClassNotFoundException cause = new
> > ClassNotFoundException("Could not resolve type ["
> >                      + this.type + "] with the currently configured
> >                       org.apache.wicket.application.IClassResolver");
> >                        throw new WicketRuntimeException(cause);
> >                }
> >             } else {
> >                 return LazyInitProxyFactory.createProxy(clazz,
> > this.locator);
> >             }
> >         }
> >     }
> >
>
> Here it is not very clear what exactly is the change. One has to diff it
> agaisnt the original code to see what you have added/removed.
>
>
> >
> > Reason:
> >
> > WicketObject.resolveClass is incorrect:
> >
> > public static <T> Class<T> resolveClass(final String className)
> >         {
> >                 Class<T> resolved = null;
> >                 try
> >                 {
> >                         if (Application.exists())
> >                         {
> >                                 resolved = (Class<T>)Application.get()
> >                                         .getApplicationSettings()
> >                                         .getClassResolver()
> >                                         .resolveClass(className);
> >                         }
> >
> >                         if (resolved == null)
> >                         {
> >                                 resolved = (Class<T>)Class.forName(
> className,
> > false,
> > Thread.currentThread()
> >                                         .getContextClassLoader());
> >                         }
> >                 }
> >                 catch (ClassNotFoundException cnfx)
> >                 {
> >                         log.warn("Could not resolve class [" + className
> +
> > "]", cnfx);
> >                 }
> >                 return resolved;
> >         }
> > s
> > Thread.currentThread().getContextClassLoader() when replicating session
> at
> > WebLogic this sometimes returns non-application classloader which ends
> with
> > mentioned ClassNotFoundException.....Also "if (resolved == null)" part
> is
> > useless if first part throws Exception....
> >
> > We use Wicket 6.21.
> >
> > 1) Either is possible to replace LazyInitProxyFactory with custom
> > implementation....
> >
>
> You can use custom IClassResolver, no ?
> One that does whatever WebLogic needs to resolve the class and don't break
> or return null.
>
>
> > 2) Or can you please put my suggested change of
> > ProxyReplacement.readResolve
> > into some patched version of 6.21?
> >
>
> patched version of 6.21 sounds like a local build that you can do.
> We can release 6.30 and you will have to upgrade.
>
>
> >
> >
> >
> >
> >
> >
> >
> > --
> > Sent from: http://apache-wicket.1842946.n4.nabble.com/Users-forum-
> > f1842947.html
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> > For additional commands, e-mail: users-help@wicket.apache.org
> >
> >
>



-- 
WBR
Maxim aka solomax

Re: Wicket's LazyInitProxyFactory runs incorrectly at WebLogic...

Posted by tomask79 <to...@embedit.cz>.
So Option two?


--
Sent from: http://apache-wicket.1842946.n4.nabble.com/Users-forum-f1842947.html

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Wicket's LazyInitProxyFactory runs incorrectly at WebLogic...

Posted by Martin Grigorov <mg...@apache.org>.
On Wed, Apr 18, 2018 at 11:53 AM, tomask79 <to...@embedit.cz> wrote:

> Hi Martin,
>
> "Here it is not very clear what exactly is the change. One has to diff it
> agaisnt the original code to see what you have added/removed. "
>
> I added following:
>
> clazz = Class.forName(type, false, this.getClass().getClassLoader());
> if (clazz == null) {
> throw Exception...
>
> I need to force the framework to use the application
> classloader...different
> to currentThread's classloader...
>
> "You can use custom IClassResolver, no ?
> One that does whatever WebLogic needs to resolve the class and don't break
> or return null. "
>
> Unfortunatelly Wicket's classResolver won't help you, because we've got a
> problem during HTTP session serialization which isn't Wicket's application
> thread....
>
> if (Application.exists())
>                          {
>                                  resolved = (Class<T>)Application.get()
>                                          .getApplicationSettings()
>                                          .getClassResolver()
>                                          .resolveClass(className);
>                          }
>
> This is skipped...and Wicket goes here...
>
>  if (resolved == null)
>                          {
>                                  resolved =
> (Class<T>)Class.forName(className, false,
>  Thread.currentThread() .getContextClassLoader());
>                          }
>
>
> which ends with ClassNotFoundException when having @SpringBean in
> WebSession
> and If WLS doesn't have ChangeAware classloader bindided to thread.
>
> Suggested changes:
>
> 1) Either to change:
>
> static class ProxyReplacement implements IClusterable {
>          private static final long serialVersionUID = 1L;
>          private final IProxyTargetLocator locator;
>          private final String type;
>
>          public ProxyReplacement(String type, IProxyTargetLocator locator)
> {
>              this.type = type;
>              this.locator = locator;
>          }
>
>          private Object readResolve() throws ObjectStreamException {
>              Class<?> clazz = WicketObjects.resolveClass(this.type);
>              if (clazz == null) {
>                  clazz = Class.forName(type, false,
>  this.getClass().getClassLoader());
>                  if (clazz == null) {
>                       ClassNotFoundException cause = new
>  ClassNotFoundException("Could not resolve type ["
>                       + this.type + "] with the currently configured
>                        org.apache.wicket.application.IClassResolver");
>                         throw new WicketRuntimeException(cause);
>                 }
>              } else {
>                  return LazyInitProxyFactory.createProxy(clazz,
>  this.locator);
>              }
>          }
>      }
>
> 2) Another possible fix (WicketObjects):
>
> public static <T> Class<T> resolveClass(final String className)
>         {
>                 Class<T> resolved = null;
>                 try
>                 {
>                         if (Application.exists())
>                         {
>                                 resolved = (Class<T>)Application.get()
>                                         .getApplicationSettings()
>                                         .getClassResolver()
>                                         .resolveClass(className);
>                         }
>
>                         if (resolved == null)
>                         {
>                                 resolved = (Class<T>)Class.forName(className,
> false,
> WicketObjects.class.getClassLoader());
>                         }
>                 }
>                 catch (ClassNotFoundException cnfx)
>                 {
>                         log.warn("Could not resolve class [" + className +
> "]", cnfx);
>                 }
>                 return resolved;
>         }
>
> Both changes have the same effect...Please would you be willing to
> propagate
> this into the patch?
>

The Thread context classloader and the one that loaded the class is not
always the same.
I'd rather add yet another "if (class == null)
{tryWithWicketObjectsClassClassLoader}" after trying with the thread
context loader.

WebLogic (like WebSphere) are rather exotic application servers and they
are known for not following the standards.
I don't want to break any other application that works fine on *normal*
servers.

Please test my suggestion and send a PR, or at least open a ticket in JIRA.


>
>
> --
> Sent from: http://apache-wicket.1842946.n4.nabble.com/Users-forum-
> f1842947.html
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>

Re: Wicket's LazyInitProxyFactory runs incorrectly at WebLogic...

Posted by tomask79 <to...@embedit.cz>.
Hi Martin,

"Here it is not very clear what exactly is the change. One has to diff it 
agaisnt the original code to see what you have added/removed. "

I added following:

clazz = Class.forName(type, false, this.getClass().getClassLoader()); 
if (clazz == null) { 
throw Exception...

I need to force the framework to use the application classloader...different
to currentThread's classloader...

"You can use custom IClassResolver, no ? 
One that does whatever WebLogic needs to resolve the class and don't break 
or return null. "

Unfortunatelly Wicket's classResolver won't help you, because we've got a
problem during HTTP session serialization which isn't Wicket's application
thread....

if (Application.exists()) 
                         { 
                                 resolved = (Class<T>)Application.get() 
                                         .getApplicationSettings() 
                                         .getClassResolver() 
                                         .resolveClass(className); 
                         } 

This is skipped...and Wicket goes here...

 if (resolved == null) 
                         { 
                                 resolved =
(Class<T>)Class.forName(className, false, 
 Thread.currentThread() .getContextClassLoader()); 
                         } 


which ends with ClassNotFoundException when having @SpringBean in WebSession
and If WLS doesn't have ChangeAware classloader bindided to thread.

Suggested changes:

1) Either to change:

static class ProxyReplacement implements IClusterable { 
         private static final long serialVersionUID = 1L; 
         private final IProxyTargetLocator locator; 
         private final String type; 
 
         public ProxyReplacement(String type, IProxyTargetLocator locator) { 
             this.type = type; 
             this.locator = locator; 
         } 
 
         private Object readResolve() throws ObjectStreamException { 
             Class<?> clazz = WicketObjects.resolveClass(this.type); 
             if (clazz == null) { 
                 clazz = Class.forName(type, false, 
 this.getClass().getClassLoader()); 
                 if (clazz == null) { 
                      ClassNotFoundException cause = new 
 ClassNotFoundException("Could not resolve type [" 
                      + this.type + "] with the currently configured 
                       org.apache.wicket.application.IClassResolver"); 
                        throw new WicketRuntimeException(cause); 
                } 
             } else { 
                 return LazyInitProxyFactory.createProxy(clazz, 
 this.locator); 
             } 
         } 
     } 

2) Another possible fix (WicketObjects):

public static <T> Class<T> resolveClass(final String className)
	{
		Class<T> resolved = null;
		try
		{
			if (Application.exists())
			{
				resolved = (Class<T>)Application.get()
					.getApplicationSettings()
					.getClassResolver()
					.resolveClass(className);
			}

			if (resolved == null)
			{
				resolved = (Class<T>)Class.forName(className, false,
WicketObjects.class.getClassLoader());
			}
		}
		catch (ClassNotFoundException cnfx)
		{
			log.warn("Could not resolve class [" + className + "]", cnfx);
		}
		return resolved;
	}

Both changes have the same effect...Please would you be willing to propagate
this into the patch?


--
Sent from: http://apache-wicket.1842946.n4.nabble.com/Users-forum-f1842947.html

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Wicket's LazyInitProxyFactory runs incorrectly at WebLogic...

Posted by Martin Grigorov <mg...@apache.org>.
Hi,

On Wed, Apr 18, 2018 at 11:10 AM, tomask79 <to...@embedit.cz> wrote:

> Hi guys,
>
> this is the continuation of
>
> http://apache-wicket.1842946.n4.nabble.com/SpringBean-
> inside-WebSession-td4680162.html
>
> We have found the root cause:
>
> Is somehow possible to replace LazyInitProxyFactory.ProxyReplacement with
> custom implementation?
>
> Why I need that? I need following code tweak:
>
> static class ProxyReplacement implements IClusterable {
>         private static final long serialVersionUID = 1L;
>         private final IProxyTargetLocator locator;
>         private final String type;
>
>         public ProxyReplacement(String type, IProxyTargetLocator locator) {
>             this.type = type;
>             this.locator = locator;
>         }
>
>         private Object readResolve() throws ObjectStreamException {
>             Class<?> clazz = WicketObjects.resolveClass(this.type);
>             if (clazz == null) {
>                 clazz = Class.forName(type, false,
> this.getClass().getClassLoader());
>                 if (clazz == null) {
>                      ClassNotFoundException cause = new
> ClassNotFoundException("Could not resolve type ["
>                      + this.type + "] with the currently configured
>                       org.apache.wicket.application.IClassResolver");
>                        throw new WicketRuntimeException(cause);
>                }
>             } else {
>                 return LazyInitProxyFactory.createProxy(clazz,
> this.locator);
>             }
>         }
>     }
>

Here it is not very clear what exactly is the change. One has to diff it
agaisnt the original code to see what you have added/removed.


>
> Reason:
>
> WicketObject.resolveClass is incorrect:
>
> public static <T> Class<T> resolveClass(final String className)
>         {
>                 Class<T> resolved = null;
>                 try
>                 {
>                         if (Application.exists())
>                         {
>                                 resolved = (Class<T>)Application.get()
>                                         .getApplicationSettings()
>                                         .getClassResolver()
>                                         .resolveClass(className);
>                         }
>
>                         if (resolved == null)
>                         {
>                                 resolved = (Class<T>)Class.forName(className,
> false,
> Thread.currentThread()
>                                         .getContextClassLoader());
>                         }
>                 }
>                 catch (ClassNotFoundException cnfx)
>                 {
>                         log.warn("Could not resolve class [" + className +
> "]", cnfx);
>                 }
>                 return resolved;
>         }
> s
> Thread.currentThread().getContextClassLoader() when replicating session at
> WebLogic this sometimes returns non-application classloader which ends with
> mentioned ClassNotFoundException.....Also "if (resolved == null)" part is
> useless if first part throws Exception....
>
> We use Wicket 6.21.
>
> 1) Either is possible to replace LazyInitProxyFactory with custom
> implementation....
>

You can use custom IClassResolver, no ?
One that does whatever WebLogic needs to resolve the class and don't break
or return null.


> 2) Or can you please put my suggested change of
> ProxyReplacement.readResolve
> into some patched version of 6.21?
>

patched version of 6.21 sounds like a local build that you can do.
We can release 6.30 and you will have to upgrade.


>
>
>
>
>
>
>
> --
> Sent from: http://apache-wicket.1842946.n4.nabble.com/Users-forum-
> f1842947.html
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>

Re: Wicket's LazyInitProxyFactory runs incorrectly at WebLogic...

Posted by Martin Grigorov <mg...@apache.org>.
On Thu, Apr 19, 2018 at 5:40 PM, tomask79 <to...@embedit.cz> wrote:

> Hi Martin,
>
> I created a Wicket 6.21 patch with following change:
>
>
A diff/patch format is much easier to review and comment on.


> static class ProxyReplacement implements IClusterable {
>         private static final long serialVersionUID = 1L;
>         private final IProxyTargetLocator locator;
>         private final String type;
>
>         public ProxyReplacement(String type, IProxyTargetLocator locator) {
>             this.type = type;
>             this.locator = locator;
>         }
>
>         private Object readResolve() throws ObjectStreamException {
>             Class<?> clazz = WicketObjects.resolveClass(this.type);
>             if (clazz == null) {
>                 try {
>                     clazz = Class.forName(this.type, false,
> WicketObjects.class.getClassLoader());
>

As I said earlier: I'd prefer to keep the old code with the thread context
CL as a first attempt and fallback to
 ProxyReplacement.class.getClassLoader()) only in case of
ClassNotFoundException.
6.x is used by many apps out there and such change may fix WebLogic but
also may break many more apps on normal web containers.
This new code will break for any application that puts Wicket jars in the
web container shared libs, like $TOMCAT_BASE/lib.


                    System.out.println("Clazz resolved through application
> classloade");
>                 } catch (ClassNotFoundException var4) {
>                     ClassNotFoundException cause = new
> ClassNotFoundException("Could not resolve type [" + this.type + "] with the
> currently configured org.apache.wicket.application.IClassResolver");
>                     throw new WicketRuntimeException(cause);
>                 }
>             }
>
>             return LazyInitProxyFactory.createProxy(clazz, this.locator);
>         }
>     }
>
> a this code solves the problem....when do you plan next 6.30 wicket
> release?
> So you could port this change in there....
>

I guess it will be released with Wicket 8.0.0 and 7.11.0. Dunno when
exactly this might be


>
> --
> Sent from: http://apache-wicket.1842946.n4.nabble.com/Users-forum-
> f1842947.html
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>

Re: Wicket's LazyInitProxyFactory runs incorrectly at WebLogic...

Posted by tomask79 <to...@embedit.cz>.
Hi Martin,

I created a Wicket 6.21 patch with following change:

static class ProxyReplacement implements IClusterable {
        private static final long serialVersionUID = 1L;
        private final IProxyTargetLocator locator;
        private final String type;

        public ProxyReplacement(String type, IProxyTargetLocator locator) {
            this.type = type;
            this.locator = locator;
        }

        private Object readResolve() throws ObjectStreamException {
            Class<?> clazz = WicketObjects.resolveClass(this.type);
            if (clazz == null) {
                try {
                    clazz = Class.forName(this.type, false,
WicketObjects.class.getClassLoader());
                    System.out.println("Clazz resolved through application
classloade");
                } catch (ClassNotFoundException var4) {
                    ClassNotFoundException cause = new
ClassNotFoundException("Could not resolve type [" + this.type + "] with the
currently configured org.apache.wicket.application.IClassResolver");
                    throw new WicketRuntimeException(cause);
                }
            }

            return LazyInitProxyFactory.createProxy(clazz, this.locator);
        }
    }

a this code solves the problem....when do you plan next 6.30 wicket release?
So you could port this change in there....

--
Sent from: http://apache-wicket.1842946.n4.nabble.com/Users-forum-f1842947.html

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org