Не удалось загрузить файл библиотеки object is not an instance of declaring class
I can't figure out how to get around this error, here is the class I'm trying to make work. Every time I try to call I method I get the error.
whenever I call runMethod I get the error. I would appreciate any insight on the problem.
public class ClassManager
private Class thisClass;
/**
Creates a Class based on the name supplied.
@param Name of the Class to instantiate
@see Class
*/
public ClassManager(String className) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException, Exception thisClass = Class.forName(className);
Constructor construct;
Class[] paramTypes = <>;
construct = thisClass.getConstructor(paramTypes);
Object[] params = <>;
Object tempObj = construct.newInstance(params);
thisClass = tempObj.getClass();
>
/**
Creates a Class based on the name supplied.
@param Name of the Class to instantiate
@see Class
*/
public ClassManager(String className, Class[] paramTypes, Object[] params) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException thisClass = Class.forName(className);
Constructor construct;
construct = thisClass.getConstructor(paramTypes);
Object tempObj = construct.newInstance(params);
thisClass = (Class)tempObj;
/**
Runs a method on the class and returns an Object if it returns
@param
@return
@see
*/
public Object runMethod(String methodName, Class[] argTypes, Object[] arguments) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, Exception Method meth;
try meth = thisClass.getMethod(methodName, argTypes);
Object retObj = meth.invoke ((Object)thisClass, arguments);
return retObj;
>
catch (Exception e) throw new Exception (e + " at ClassManager.runMethod");
>
I'm trying to use JavaMelody Spring Boot Starter (1.72.0) in application built upon Spring Boot 2.0.1.RELEASE which in turn uses HikariCP 2.7.8 connection pool. But the application fails to start due to the following exception:
If I comment out the dependency from JavaMelody starter, application starts fine.
ℹ️ During debugging I've found out that the exception occur when initializing logic tries to call method public java.lang.String com.zaxxer.hikari.HikariConfig.getConnectionTestQuery() on the following classes instances:
While it seems not a bug of JavaMelody (but HikariCP config in SpringBoot2) I'd like you to check my groundwork and may be propose a workaround.
Additional info on reproducing the issue can be provided.
The text was updated successfully, but these errors were encountered:
решение:
- Метод отражения определяется как статический, так что отражение не нужно существовать;
- Установите при вызове метода отражения, такого как метод .invoke (Refrect.NewInstance (), «Hoki»);
Toparvion commented May 10, 2018
I've eventually found relatively admissible workaround - I've switched Spring Boot back to Tomcat JDBC pool (the one it used until 2.x generation). Thanks to full conformation to DataSource interface, this pool does not cause the problem to arise.
You can find the fix in the second commit to sample project.
5. Wondering off into the Sunset
It looks like org.jboss.envers.entities.mapper.MultiPropertyMapper.mapCollectionChanges(String, PersistentCollection, Serializable, Serializable) (which each of the four envers event listeners gets into) may have something to do with the mismatch. But I haven’t been able to pinpoint the cause yet. Seems like it’s likely a configuration problem on our end — though I don’t know where — our Hibernate configuration being:
The property placeholders in the above configuration are filled in as follows:
Ошибка: Объект не является экземпляром декларирования класса, определенный класс не создан.
Интеллектуальная рекомендация
Нажмите три числа от большого до небольшого выхода
Toparvion commented May 4, 2018 •
@evernat,
I've done some research and eventually found out the source of the difference.
The use of Spring CGLIB proxy here is provided neither by Hikari nor by Spring Boot itself. There is third party here - Spring Cloud Commons and its dynamic refresh feature. To facilitate on-the-fly configuration refresh, Spring Cloud uses LockedScopedProxyFactoryBean which is indirectly mentioned in documentation:
Refresh scope beans are lazy proxies that initialize when they are used (i.e. when a method is called), and the scope acts as a cache of initialized values
In our case it is setBeanFactory method that triggered initialization of the proxy.
💡 As a proof-of-concept I created a sample project that reliably reproduces the issue. To switch between successful and failure scenarios just [un]comment line 39 in build.gradle.
Actually I don't see any simple solution now. But I'm going to try to apply a workaround with the methods I found during debugging. Please let me know if you have any ideas.
Интеллектуальная рекомендация
evernat commented May 10, 2018
yes, that's a a better workaround
Нажмите три числа от большого до небольшого выхода
Обучение HTML-записи (1)
Ссылки на учебные ресурсы Обучающее видео html element label значение периодической таблицы элементов Документ Знания чаевые единый формат HTML содержание имя тега> Теги могут.
evernat commented Apr 30, 2018 •
I do not reproduce the exception using spring boot 2.0.1.
I have almost the same stack-trace, but before the line org.springframework.boot.jdbc.metadata.HikariDataSourcePoolMetadata.getValidationQuery(HikariDataSourcePoolMetadata.java:66) there is if (dataSource instanceof HikariDataSource) at line 64, in spring boot 2.0.1.
So in my case, the test is false (because dataSource is not an instance of HikariDataSource when wrapped in a proxy, as you said yourself) and the method returns null and the poolMetadata.getValidationQuery() is then not called.
And so I do not have any exception.
So can you give the source of a simple project to reproduce the issue?
evernat commented Apr 30, 2018 •
I do not reproduce the exception using spring boot 2.0.1.
I have almost the same stack-trace, but before the line org.springframework.boot.jdbc.metadata.HikariDataSourcePoolMetadata.getValidationQuery(HikariDataSourcePoolMetadata.java:66) there is if (dataSource instanceof HikariDataSource) at line 64, in spring boot 2.0.1.
So in my case, the test is false (because dataSource is not an instance of HikariDataSource when wrapped in a proxy, as you said yourself) and the method returns null and the poolMetadata.getValidationQuery() is then not called.
And so I do not have any exception.
So can you give the source of a simple project to reproduce the issue?
Прямой разговор об использовании vuex в проекте vue-cli
Что такое Vuex? монтаж Напишите код: Добавьте этот файл в main.js Вот 4 основных концепции. State Откройте index.js под файлом магазина Подготовьте два компонента (назовите как хотите) Header.vue Foot.
LeetCode: Интервью 04.04. Проверьте баланс
Глубокоищите дерево, получите высоту левого поддерева и правого поддерева, если две разницы высоты превышают 1, это не дерево баланса .
Система новостей Burdock (1) Что такое генератор классов сущностей?
предисловие В настоящее время автор изучает систему выпусков новостей о лопухе с невероятной скоростью. Сегодня я наконец-то решил, что в этой колонке написано что-то новое, чего я не понимаю при разр.
Система новостей Burdock (1) Что такое генератор классов сущностей?
предисловие В настоящее время автор изучает систему выпусков новостей о лопухе с невероятной скоростью. Сегодня я наконец-то решил, что в этой колонке написано что-то новое, чего я не понимаю при разр.
LeetCode: Интервью 04.04. Проверьте баланс
Глубокоищите дерево, получите высоту левого поддерева и правого поддерева, если две разницы высоты превышают 1, это не дерево баланса .
evernat commented May 9, 2018
Thanks for finding the cause and for the sample project.
As a workaound and without other ideas, you can add the following in the application.properties file of the sample project, but it will also disable the monitoring of jdbc connections and of sql requests:
That said I don't know why Spring Cloud is messing up with the Spring Boot dataSource and with the Spring Boot proxies (as a reminder, the HikariDataSource does not have a RefreshScope annotation).
java.lang.IllegalArgumentException: object is not an instance of declaring class
Ошибка была сообщена, когда Java отражена.
Причина в том, что не существует создания
Эта линия неверна.
Наследование рода типов пустых методов строительства
Хорошо, это решено.
Обучение HTML-записи (1)
Ссылки на учебные ресурсы Обучающее видео html element label значение периодической таблицы элементов Документ Знания чаевые единый формат HTML содержание имя тега> Теги могут.
Прямой разговор об использовании vuex в проекте vue-cli
Что такое Vuex? монтаж Напишите код: Добавьте этот файл в main.js Вот 4 основных концепции. State Откройте index.js под файлом магазина Подготовьте два компонента (назовите как хотите) Header.vue Foot.
Toparvion commented Sep 11, 2018
3. Tracking down the mismatch
The HashMap comes into BasicPropertyAccessor.BasicSetter.set() as an Object parameter named target. Let’s follow the call stack to see where target is coming from.
- As an Object named entity to PojoEntityTuplizer(AbstractEntityTuplizer).setIdentifier();
- by SingleTableEntityPersister(AbstractEntityPersister).setIdentifier(), which received it as a As an Object named object
- from DefaultSaveEventListener(AbstractSaveEventListener).performSave(), which received it as an Object named entity
- from DefaultSaveEventListener(AbstractSaveEventListener).saveWithGeneratedId(), which received it as an Object named entity
- from DefaultSaveEventListener(DefaultSaveOrUpdateEventListener).saveWithGeneratedOrRequestedId(SaveOrUpdateEvent event), which called event.getEntity().
Now this org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(SaveOrUpdateEvent) call is interesting: it passes event.getEntity() and event.getEntityName() to saveWithGeneratedId(). We’ll want to watch and see how Entity and EntityName get into the SaveOrUpdateEvent.
So, continuing on down the call stack:
- SaveOrUpdateEvent event comes into DefaultSaveEventListener.saveWithGeneratedOrRequestedId(SaveOrUpdateEvent)
- from DefaultSaveEventListener(DefaultSaveOrUpdateEventListener).entityIsTransient(SaveOrUpdateEvent)
- from DefaultSaveEventListener.performSaveOrUpdate(SaveOrUpdateEvent)
- from DefaultSaveEventListener(DefaultSaveOrUpdateEventListener).onSaveOrUpdate(SaveOrUpdateEvent)
- from SessionImpl.fireSave(SaveOrUpdateEvent)
- from SessionImpl.save(String, Object).
Ok, it’s in this last spot, org.hibernate.impl.SessionImpl.save(String, Object), that another interesting thing happens. The implementation of this method is the one-liner:
So it looks wrong even back here.
3.1. PersistentCollectionChangeData is wrong too
One level deeper, we get to org.jboss.envers.synchronization.work.PersistentCollectionChangeWorkUnit.perform(Session, Object), where we see this line of code:
Here, the persistentCollectionChangeData object’s entityName is “com.ontsys.db.inventory.products.po.ProductPO”, but the data is a HashMap.
3.2. Whence this errant persistentCollectionChangeData object?
This persistentCollectionChangeData object is one element of the private final List collectionChanges , which is set in the constructor of org.jboss.envers.synchronization.work.PersistentCollectionChangeWorkUnit. It looks from the javadoc for org.jboss.envers.entities.mapper.PropertyMapper.mapCollectionChanges() that it’s the Serializable snapshot parameter coming into the PersistentCollectionChangeWorkUnit constructor that is the wrong type (HashMap instead of ProductPO).
3.3. The creation of the PersistentCollectionChangeWorkUnit: onCollectionAction()
It is here that our debugging forks away from the JTA transaction commit call that kicks off a beforeCompletion() Synchronization event that results in the envers PersistentCollectionChangeWorkUnit.peform() call. The bad data seems to be getting passed in when this PersistentCollectionChangeWorkUnit is constructed. Let’s see where that is.
Searching for all references in this project to the PersistentCollectionChangeWorkUnit constructor (using Eclipse’s handy Search -> References -> Project) yields just one reference: org.jboss.envers.event.VersionsEventListener.onCollectionAction(AbstractCollectionEvent, PersistentCollection, Serializable, CollectionEntry).
The second and third parameters to onCollectionAction() are PersistentCollection newColl and Serializable oldColl. I think it’s one of these that’s the HashMap where we would expect it to be a ProductPO.
onCollectionAction() is called by just three methods, all in org.jboss.envers.event.VersionsEventListener:
- onPostRecreateCollection()
- onPreRemoveCollection()
- onPreUpdateCollection()
2. Examinin’ a Known Good method.invoke()
When we set the breakpoint hit count on the previously mentioned method.invoke() to 77 instead of 78, it breaks there with these values (again, gotten by Ctrl+Shift+D-ing :
- method= (java.lang.reflect.Method) public void com.ontsys.fw.hibernatesupport.RevisionEntityPO.setId(java.lang.Integer)
- target=(com.ontsys.fw.hibernatesupport.RevisionEntityPO) com.ontsys.fw.hibernatesupport.RevisionEntityPO@103a032
- value= (java.lang.Integer) 5874
Hmm, notice that the Method is a reflective instance of RevisionEntityPO.setId(), and the target object is a RevisionEntityPO (i.e., the target matches the method it’s being called on? That’s not the case where the exception gets thrown — there, it’s BaseTO.setKey() being called on a java.util.HashMap. I wonder where this mismatch is coming from, that 78th time into BasicPropertyAccessor.BasicSetter.set()?
UPDATE from 10 Sep 2018
Meanwhile Spring Cloud reached its GA stage on 2.x family and by this moment its freshest version is Finchley.SR1. With this version the exception described above noticeably changed:
The root is java.lang.ClassCastException: com.sun.proxy.$Proxy89 cannot be cast to com.zaxxer.hikari.HikariDataSource . In other words, there is a mix of proxy mechanism implementations and it seems quite wider problem than just a rare unlucky combination of dependencies.
I.e. no new proxy should be created in case the given object is already proxied. But unfortunately isProxyAlready() method checks for JDK proxy only and knows nothing about CGLIB proxies. As a result it returns false and allows successive logic perform. This seems wrong behavior.
In our last episode we were seeing an IllegalArgumentException when Method.invoke() was called, and the message inside the exception was:
object is not an instance of declaring class
Let’s see if we can figure out what’s going on here.
To review, the call that fails is in org.hibernate.property.BasicPropertyAccessor.BasicSetter.set(), line 66, where it calls
And performing a Display (Ctrl+Shift+D) operation to show the values of each of the parts of this call:
Then we get the object is not an instance of declaring class-containin’ IllegalArgumentException.
1. Focusing on the Target
Let’s look at the basic question first: is target a com.ontsys.fw.datatypes.BaseTO ? It looks like it’s a java.util.HashMap.
Not having much experience with reflection (with Java reflection anyway; I have some experience with personal reflection… ;), I don’t really know what I’m seeing here. Let’s try this breakpoint with a call that works, and evaluate method and target there.
Right now the breakpoint hit count is set to 78, as it’s the 78th call to BasicPropertyAccessor.BasicSetter.set() that fails.
Toparvion commented May 10, 2018
The suggested workaround does allow the application to start but it hardly pretends to be a solution because one of the main goals of using JavaMelody in the project is monitoring of JDBC connections and SQL queries.
Other workarounds I've mentioned early also passed by as Spring Cloud forces the use of LockedScopedProxyFactoryBean which in turn applies CGLIB proxy as pointed out by proxyTargetClass flag:
Perhaps there is a way to alternate value of proxyTargetClass flag but I don't see it so far.
4. No Clear Badness Seen at the VersionsEventListener events
I’ve put a simple breakpoint on each of the three collection-related versions events mentioned in the bulleted list above. Here are the breakpoints we hit, in order, before the fateful method.invoke() where we die:
- onPostRecreateCollection():
- thePersistentCollection passed in is a PersistentSet: [com.ontsys.db.inventory.products.po.ProductPO@11bbdbb]
- the Serializable is passed as null
- the affectedOwnerEntityName (which is later read out as entityName) is “com.ontsys.db.inventory.products.po.ProductSetPO”
- the PersistentCollection passed in is a PersistentBag: [com.ontsys.db.inventory.products.po.DelinquencyBucketPO@14e7ad5, com.ontsys.db.inventory.products.po.DelinquencyBucketPO@1f5a659];
- the Serializable is again null; and
- the affectedOwnerEntityName is com.ontsys.db.inventory.products.po.ProductPO
- the PersistentCollection passed in is null;
- the Serializable is (java.util.HashMap)
- the PersistentCollection passed in is a PersistentSet: [com.ontsys.db.inventory.products.po.ProductPO@11bbdbb];
- the Serializable is null; and
- the affectedOwnerEntityName is com.ontsys.db.inventory.products.po.ProductSetPO
Hmm. None of these looks obviously wrong to my admittedly non-expert eyes. Even in step 3 when the Serializable is a HashMap, it’s a HashMap containing a ProductPO mapping, which looks plausible.
Читайте также:
- Какой объем видеопамяти необходим для хранения трех страниц изображения при условии что разрешающая
- Что входит в комплект при покупке компьютера
- Какой официальный сайт utorrent
- Что делать если случайно изменил тип файла
- В процессе использования компьютерных технологий можно выделить следующие основные линии развития