cayenne-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Andrus Adamchik <and...@objectstyle.org>
Subject Re: Cayenne and classpath question and help
Date Thu, 17 Oct 2019 18:03:37 GMT
I suspect reloaded classes come through their own ClassLoader. So what mechanism are you using
for dynamic reloading and what is the structure of class loaders?

You can control CL behavior via ClassLoaderManager which is an injectable service in Cayenne.
By default it is implemented via DefaultClassLoaderManager, that looks up a CL like this:

  ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
  if (classLoader == null) {
    classLoader = DefaultClassLoaderManager.class.getClassLoader();
  }

If you can figure out CLs structure in your app, you can either implement your own ClassLoaderManager,
or set a proper thread class loader.

Andrus


> On Oct 16, 2019, at 11:24 PM, Andrew Willerding <awillerding@itsurcom.com> wrote:
> 
> Hi,
> 
> I have an application that dynamically loads jar files and reloads them when they are
changed.  Unfortunately I'm have an issue getting Cayenne to see the classes inside one of
these dynamically loaded jar files. I have some test code that looks roughly like this.
> 
> import com.dbclientbase.Database.Account;
> public class blah
> 
>   public testMethod(){
> 
>             Account ac = new Account();  // This object instantiates without an error
so it's visible to app outside of Cayenne
> 
>             ObjectContext oc = DBClientBase.getObjectContext(); // This method generates
the ServerRuntime and fails to get an ObjectContext to work with (error below)
> 
>  }
> }
> 
> The error output below seems to suggest that Cayenne cannot access the Account class
although I can successfully instantiate a non-Cayenne object.  What can I do to ensure that
Cayenne also has access to the contents of a dynamically loaded and reloaded jar file?  I
have found references to AdhocObjectFactory.getClassLoader()  but I can't find any examples
on how to use it and I'm quite at a loss on how to even begin use it.
> 
> Thanks,
> 
> Andrew
> 
> 
> Exception==>org.apache.cayenne.configuration.server.DataDomainLoadException: [v.4.1.B2
May 04 2019 09:30:14] DataDomain startup failed: Invalid class: com.dbclientbase.Database$Account
>     at org.apache.cayenne.configuration.server.DataDomainProvider.get(DataDomainProvider.java:123)
>     at org.apache.cayenne.configuration.server.DataDomainProvider.get(DataDomainProvider.java:60)
>     at org.apache.cayenne.di.spi.CustomProvidersProvider.get(CustomProvidersProvider.java:39)
>     at org.apache.cayenne.di.spi.FieldInjectingProvider.get(FieldInjectingProvider.java:43)
>     at org.apache.cayenne.di.spi.DefaultScopeProvider.get(DefaultScopeProvider.java:50)
>     at org.apache.cayenne.di.spi.DefaultInjector.getInstance(DefaultInjector.java:139)
>     at org.apache.cayenne.di.spi.FieldInjectingProvider.value(FieldInjectingProvider.java:103)
>     at org.apache.cayenne.di.spi.FieldInjectingProvider.injectMember(FieldInjectingProvider.java:68)
>     at org.apache.cayenne.di.spi.FieldInjectingProvider.injectMembers(FieldInjectingProvider.java:59)
>     at org.apache.cayenne.di.spi.FieldInjectingProvider.get(FieldInjectingProvider.java:44)
>     at org.apache.cayenne.di.spi.DefaultScopeProvider.get(DefaultScopeProvider.java:50)
>     at org.apache.cayenne.di.spi.DefaultInjector.getInstance(DefaultInjector.java:134)
>     at org.apache.cayenne.configuration.CayenneRuntime.newContext(CayenneRuntime.java:124)
>     at com.dbclientbase.DBClientBase.getObjectContext(DBClientBase.java:100)
>     at java.base/java.lang.Thread.run(Thread.java:834)
> Caused by: org.apache.cayenne.di.DIRuntimeException: Invalid class: com.Database$Account
>     at org.apache.cayenne.di.spi.DefaultAdhocObjectFactory.getJavaClass(DefaultAdhocObjectFactory.java:128)
>     at org.apache.cayenne.util.Util.getJavaClass(Util.java:632)
>     at org.apache.cayenne.map.ObjEntity.getJavaClass(ObjEntity.java:265)
>     at org.apache.cayenne.map.EntityResolver.initCallbacks(EntityResolver.java:141)
>     at org.apache.cayenne.map.EntityResolver.getCallbackRegistry(EntityResolver.java:163)
>     at org.apache.cayenne.access.DataDomain.addListener(DataDomain.java:791)
>     at org.apache.cayenne.access.DataDomain.addSyncFilter(DataDomain.java:748)
>     at org.apache.cayenne.configuration.server.DataDomainProvider.createAndInitDataDomain(DataDomainProvider.java:188)
>     at org.apache.cayenne.configuration.server.DataDomainProvider.get(DataDomainProvider.java:117)
>     ... 16 more
> Caused by: java.lang.ClassNotFoundException: com.dbclientbase.Database.Account
>     at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
>     at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
>     at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
>     at java.base/java.lang.Class.forName0(Native Method)
>     at java.base/java.lang.Class.forName(Class.java:398)
>     at org.apache.cayenne.di.spi.DefaultAdhocObjectFactory.getJavaClass(DefaultAdhocObjectFactory.java:93)
>     ... 24 more
> 


Mime
View raw message