I have a problem with generated static metamodel classes in EclipseLink.
In my project I firstly generated static metamodel classed for my entities using:
1) org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor and IntelliJ IDEA
and this classes have been generated to: target/generated-sources
Then I try to use such Hibernate generated metamodel classes (ex. below) with EclipseLink (GlassFish embedded), but lines of code that contains references to metamodel attributes throws NullPointerException exception:
SingularAttribute<Employee, String> descriptionAttr = Employee_.description;
predicates.add(criteriaBuilder.like(employee.get(descriptionAttr), "%" + description + "%"));
Here emploee.get( >> null << ) throws exception.
#Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
#StaticMetamodel(Employee.class)
public abstract class Employee_ extends pl.salonea.entities.NaturalPerson_ {
public static volatile SetAttribute<Employee, Skill> skills;
public static volatile SetAttribute<Employee, ProviderService> suppliedServices;
public static volatile SetAttribute<Employee, EmployeeRating> receivedRatings;
public static volatile SingularAttribute<Employee, String> description;
public static volatile SetAttribute<Employee, Education> educations;
public static volatile SingularAttribute<Employee, String> jobPosition;
public static volatile SetAttribute<Employee, TermEmployeeWorkOn> termsOnWorkStation;
}
2) Next I thought that this metamodel classes maybe are implementation specific. So I generated them analogically with EclipseLink using
org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProcessor and target/generated-sources-eclipselink (as on picture)
At the end I have something like this directory stracture with metamodel:
3) I am also using in build.gradle such configuration to as I think include this generated sources in project:
if(hasProperty('jboss')) {
sourceSets {
main {
java {
srcDir 'target/generated-sources/'
}
}
}
} else {
sourceSets {
main {
java {
srcDir 'target/generated-sources-eclipselink/'
}
}
}
}
This way I want to use Hibernate generated classes with Jboss and EclipseLink generated classes with EclipseLink.
4) Such configuration works only if running on WilfFly/Hibernate but not on GlassFish/EclipseLink here is this NullPointerException
5) In persistence.xml I have more over EclipseLink generation using such property for one Persistence Unit
<property name="eclipselink.canonicalmodel.subpackage" value="metamodel" />
and such property for second Persistence Unit (to avoid duplicate conflict)
<property name="eclipselink.canonicalmodel.subpackage" value="metamodel_local" />
But I'm trying not to use this generation. It is in subpackage and in my code I only import previously generated metamodel classes.
The reason is that I would like to have in the same namespace metamodel classes generated by Hibernate/Eclipse and use them appropriately.
However if Hibernate generated metamodel classes could be also work with EclipseLink there won't be problem to using only one generation.
6) Moreover I cant use metamodel classes generated by EclipseLink persistence.xml property as they are regenerated each time I run/build my project. And I need in my code to manually modify two metamodel classes as they are inherited from single abstract metamodel class. Here I am overriding in subclasses AbstractType with ConcreteType on SetAttribute of metamodel class.
7) At the end I paste error I'm getting while running integration test with such configuration of metamodel classes
Caused by: java.lang.NullPointerException
at org.eclipse.persistence.internal.jpa.querydef.FromImpl.get(FromImpl.java:263)
at pl.salonea.ejb.stateless.EmployeeFacade.findByMultipleCriteria(EmployeeFacade.java:295)
at pl.salonea.ejb.stateless.EmployeeFacade.findByMultipleCriteria(EmployeeFacade.java:269)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1081)
at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1153)
at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:4786)
at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:656)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:46)
at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:52)
at sun.reflect.GeneratedMethodAccessor113.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doCall(SystemInterceptorProxy.java:163)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:140)
at sun.reflect.GeneratedMethodAccessor141.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:369)
at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:4758)
at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4746)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:212)
... 149 more
-I'm checking EclipseLink sources:
public <Y> Path<Y> get(SingularAttribute<? super X, Y> att){
if (att.getPersistentAttributeType().equals(
PersistentAttributeType.BASIC)) {
return new PathImpl<Y>(
this, this.metamodel, att.getBindableJavaType(),
this.currentNode.get(att.getName()), att);
} else {
Class<Y> clazz = att.getBindableJavaType();
Join join = new JoinImpl<X, Y>(
this, this.metamodel.managedType(clazz),
this.metamodel, clazz,
this.currentNode.get(att.getName()), att);
this.joins.add(join);
return join;
}
}
FromImpl.java:263 is condition of if statement so it looks like att.getPersistentAttributeType() returns null.
It would be good if you'll file a bug against EclipseLink on https://bugs.eclipse.org/bugs/enter_bug.cgi?product=EclipseLink
Component is JPA. Please copy-paste this description there and provide some test-case (sample application with this metamodel) to let us reproduce it and develop some fix.
The problem can be in the failed initialization Canonical Metamodel.
You can investigate yours eclipselink log for checking something like that:
Could not load the field named [...] on the class [...]
IllegalArgumentException: Can not set static ... field ... to ...
In my case after fixing initialization, NPE had gone.
I know this is an old ticket but i still wanted to let you guys know how we fixed the problem. Especially the last nullpointer exception.
The problem is that your entitimanager is not loaded when you are using your Criteriabuilder for the first time.
To solve this problem you can set following in you persistence.xml
<property name="eclipselink.deploy-on-startup" value="true" />
Related
I'm implementing a JavaEE8 application using CDI and running on an Open Liberty (v20.0.0.4). The application has a event-triggered job, which runs some code in an separate thread using the ThreadPoolExecutor like this:
#Singleton
public class MyJobExecutorService {
#PostConstruct
public void init() {
thredPoolExecutor = new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
}
public void runJob(MyConfigs configs) {
thredPoolExecutor.submit(() -> new MyJobRunnable(configs).run());
}
}
The job gets data from the underlying sql database using an EntityManager, which is injected in the data access class and produced like following. My querys are written using querydsl (which should not be relevant).
public class EntityManagerProducer {
#PersistenceContext(unitName = "my-unit")
private EntityManager entityManager;
#Produces
#Dependent
public EntityManager getEntityManager() {
return entityManager;
}
}
My persistence.xml looks like this:
<persistence ...>
<persistence-unit name=my-unit">
<jta-data-source>jdbc/datasource</jta-data-source>
</persistence-unit>
</persistence>
I have no issues accessing the database from the main thred, but the job throws a NullPointerException with the following stacktrace (and no further information):
com.ibm.ws.jpa.management.JPATxEntityManager.getEMInvocationInfo(JPATxEntityManager.java:213)
com.ibm.ws.jpa.management.JPATxEntityManager.getEMInvocationInfo(JPATxEntityManager.java:164)
com.ibm.ws.jpa.management.JPAEntityManager.getDelegate(JPAEntityManager.java:402)
com.querydsl.jpa.impl.JPAProvider.getTemplates(JPAProvider.java:61)
com.querydsl.jpa.impl.JPAQuery.<init>(JPAQuery.java:48)
com.querydsl.jpa.impl.JPAQueryFactory.query(JPAQueryFactory.java:138)
com.querydsl.jpa.impl.JPAQueryFactory.select(JPAQueryFactory.java:81)
com.querydsl.jpa.impl.JPAQueryFactory.selectFrom(JPAQueryFactory.java:111)
my.application.MyRepository.getAll(DataAccess.java:67)
sun.reflect.GeneratedMethodAccessor1888.invoke(UnknownSource)
java.lang.reflect.Method.invoke(Method.java:498)
org.jboss.weld.bean.proxy.AbstractBeanInstance.invoke(AbstractBeanInstance.java:38)
org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:106)
my.application.MyRepository$Repository$Serializable$925348889$Proxy$_$$_WeldClientProxy.getAll(UnknownSource)
sun.reflect.GeneratedMethodAccessor1887.invoke(UnknownSource)
java.lang.reflect.Method.invoke(Method.java:498)
org.jboss.weld.bean.proxy.AbstractBeanInstance.invoke(AbstractBeanInstance.java:38)
org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:106)
my.application.DataAccess$587668909$Proxy$_$$_WeldClientProxy.getAllData(UnknownSource)
my.application.job.MyDefaultJob.runJob(MyDefaultJob.java:50)
sun.reflect.GeneratedMethodAccessor1886.invoke(UnknownSource)
java.lang.reflect.Method.invoke(Method.java:498)
org.jboss.weld.bean.proxy.AbstractBeanInstance.invoke(AbstractBeanInstance.java:38)
org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:106)
my.application.job.MyJob$588111896$Proxy$_$$_WeldClientProxy.runJob(UnknownSource)
my.application.job.MyJobExecutorService$MyRunnable.run(MyJobExecutorService.java:59)
my.application.job.MyJobExecutorService.lambda$runJob$0(MyJobExecutorService.java:36)
my.application.job.MyJobExecutorService$$Lambda$280/00000000A8128A20.run(UnknownSource)
java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
java.util.concurrent.FutureTask.run(FutureTask.java:266)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
java.lang.Thread.run(Thread.java:823)
Why am I getting this exception and how can I fix this? Activating the jpa an concurrency features in the server.xml of the application server didnt help. Thanks a lot.
Enabling the concurrent-1.0 feature alone doesn't do anything unless you are using the managed resources that it provides which capture the context of the application component (such as its java:comp name space and so forth) and makes it available when running the tasks that are submitted to it.
If you must use a ThreadPoolExecutor in order to manipulate its queue in some way beyond enforcing concurrency constraints (ManagedExecutorService can impose concurrency constraints via a configurable concurrencyPolicy), the simplest way to continue using a ThreadPoolExecutor is by supplying it with a ManagedThreadFactory,
#PostConstruct
public void init() {
ManagedThreadFactory threadFactory = InitialContext.doLookup(
"java:comp/DefaultManagedThreadFactory");
thredPoolExecutor = new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(),
threadFactory);
}
ManagedThreadFactory captures the context that is present on the thread from which it is initially looked up. You'll need to decide if there is a better place for it than your init() method based on what context you want it to provide to your ThreadPoolExecutor tasks.
You should also be aware that any use of ThreadPoolExecutor (even in combination with a ManagedThreadFactory or ContextService) bypasses use of the Liberty global thread pool.
I have an issue with the #JobScope annotation.
I'm using spring-batch, with spring-boot, so no xml. I'm also using hibernate, and wish to use it in my readers.
Here is my item reader :
#Bean(name = "readerFactures")
public ItemReader<XFctFacture> readerFactures(SessionFactory sessionFactory) {
HibernateCursorItemReader itemReader = new HibernateCursorItemReader();
itemReader.setQueryString("from XFctFacture where typeFacture=1 and statut=1");
itemReader.setSessionFactory(sessionFactory);
return itemReader;
}
And everythink works fine, so far ... :)
But now I want to access to a parameter from my job, so I need to annotate my reader with the #JobScope.
So my new code is :
#Bean(name = "readerFactures")
#JobScope
public ItemReader<XFctFacture> readerFactures(SessionFactory sessionFactory) {
HibernateCursorItemReader itemReader = new HibernateCursorItemReader();
itemReader.setQueryString("from XFctFacture where typeFacture=1 and statut=1");
itemReader.setSessionFactory(sessionFactory);
return itemReader;
}
And with this, when I execute the job, I have the following exception
java.lang.NullPointerException: null
at org.springframework.batch.item.database.HibernateCursorItemReader.doRead(HibernateCursorItemReader.java:155) ~[spring-batch-infrastructure-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.read(AbstractItemCountingItemStreamItemReader.java:88) ~[spring-batch-infrastructure-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_71]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_71]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_71]
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_71]
The cursor is null, it appears that my ItemReader had never been opened.
Any clues ?
Thanks
I've searched now for days to find some solution for my, in my opinion not too hard but obviously unsolvable problem.
I have an EAR project containing Some EJB, a web client (works fine) and now I added an Application Client Module.
As everything is in the same project, I thought a simple #EJB injection in the main class of the application client would do. I also tried a JNDI lookup.
I use eclipse and glassfish as a server and tried to run the application 1. in eclipse (there my injected bean is just null) and 2. downloaded the client-stub from the glassfish administration and tried to start it with sh appclient -client (or -jar) OmazanClient.jar (and also the other two jars hidden in the client-stub folder). There I get mostly a "ClassNotFoundExeption:Main" like
java.lang.ClassNotFoundException: Main
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at org.glassfish.appclient.client.acc.ACCClassLoader.findClass(ACCClassLoader.java:212)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at org.glassfish.appclient.client.acc.FacadeLaunchable.getMainClass(FacadeLaunchable.java:262)
at org.glassfish.appclient.client.acc.AppClientContainer.setClient(AppClientContainer.java:324)
at org.glassfish.appclient.client.acc.AppClientContainerBuilder.createContainer(AppClientContainerBuilder.java:185)
at org.glassfish.appclient.client.acc.AppClientContainerBuilder.newContainer(AppClientContainerBuilder.java:172)
at org.glassfish.appclient.client.AppClientFacade.createContainerForAppClientArchiveOrDir(AppClientFacade.java:492)
at org.glassfish.appclient.client.AppClientFacade.createContainer(AppClientFacade.java:454)
at org.glassfish.appclient.client.AppClientFacade.prepareACC(AppClientFacade.java:269)
at org.glassfish.appclient.client.acc.agent.AppClientContainerAgent.premain(AppClientContainerAgent.java:82)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:323)
at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:338)
So for the injection, my code looks like:
public class Main {
#EJB (mappedName="ejb/customerBean")
public static CustomerInterface customerBean;
#EJB (mappedName="ejb/productBean")
public static ProductInterface productBean;
public static void main(String[] args) {
try{
Main m = new Main();
m.runDialog();
}
catch (Exception e){
e.printStackTrace();
}
}
/* (non-Java-doc)
* #see java.lang.Object#Object()
*/
public Main() {
super();
}
private void runDialog() throws Exception{
System.out.println("Test");
List<ProductDTO> productList = productBean.getAllProducts();
...
My remote interface looks like this:
#Remote
public interface ProductInterface {
public int addProduct(String productName);
public void deleteProduct(int prodid);
public void updateProduct(int prodid, String newName);
List<ProductDTO> getAllProducts();
...
My implementation is this:
/**
* Session Bean implementation productInterface
* */
#Stateless(mappedName="ejb/productBean")
#LocalBean
#WebService
public class ProductBean implements ProductInterface {
#EJB ProductEAO eao;
#EJB Conversion conv;
/**
* Default constructor.
*/
public ProductBean() {
// TODO Auto-generated constructor stub
}
#Override
public int addProduct(String prodName) {
return eao.addProduct(prodName);
}
#Override
public List<ProductDTO> getAllProducts() {
List<ProductDTO> result = new ArrayList<ProductDTO>();
List<Product> allProducts = eao.allProducts();
for (Product pr : allProducts) {
ProductDTO ci = conv.fromProduct(pr);
result.add(ci);
}
return result;
}
... and so on (all methods required by the interface are implemented, just try to keep it shorter here)
and the MANIFEST.MF is just
Manifest-Version: 1.0
Main-Class: Main
I've tried a lot like JNDI lookup, giving the bean names (see example) etc. But either the interface is not found (lookup) or the bean simply null.
How ever I am also not quite sure how to run the application client. I thought glassfishs appclient is the right starting point? It shall be a console-interaction so no swing components or anything similar.
Now I'd be thankful for any suggestions what I might have missed.
Cheers :)
Found a solution. Somehow, JNDI works now. Another problem was that my db query returned an Object and not primitive value or string - this caused a buffer error.
However, I am still confused on how to export an run an application client correctly. Maybe someone has an idea?!
There is a good example here: Create and Run a JEE6 Client Application with Netbeans 6.8 and Glassfish V3 - Part 2: Enhancing and Deploying the Application. It is a few years old, but it does give a pretty good overview.
I am somewhat puzzled about Spring's classloading behavior inside an eclipse OSGi container (which is the basis for the TIBCO ActiveMatrix runtime I am trying to get this running on) and boiled this down to the below simple example.
In it (the TestComponent object is created and called inside an OSGi bundle's Activator class, but I don't think that this is important here) I first create an object direcly, just to double-check, that its class exists and can be instantiated. This of course works as one would expect...
Second, I want to create a second object of that very same class using Spring (as I originally intended), but this fails with a ClassNotFoundException.
Spring claims, it can't find that class (even though the package and class name definitely match), so I even added a .setClassLoader(...) call to pass it the very same classloader that just successfully loaded that very same class, but Spring still fails to locate that class.
Any clue of why that is so? I have ran out of ideas. What am I missing?
Later edit: I just had to realize, that it is NOT the ...getBean(...)-method call that crashes, but rather already the ClassPathXmlApplicationContext()-constructor. I.e. the object is already created in that constructor and not only later in the subsequent getBean(...)-method call. Thus my attempt to pass-in the classloader is futile as it already comes to late. So the question thus rather is: how can I pass-in the context's class loader to that constructor (or to the factory or whatever Spring uses internally to create the ClassPathXmlApplicationContext object)?
My example:
I first defined an interface for the class to be created via Spring:
package com.example.some_package_0;
public interface SomeInterface
{
public String getSomeString();
}
... and a class, implementing this interface:
package com.example.some_package_1;
import com.example.some_package_0.SomeInterface;
public class SomeClassA implements SomeInterface
{
private String someProperty;
public void setSomeProperty(String someProperty) {
this.someProperty = someProperty;
}
public String getSomeString() {
return this.someProperty;
}
}
My Test-program reads
public class TestComponent
{
import com.example.some_package_0.SomeInterface;
import com.example.some_package_1.SomeClassA;
public void test() {
SomeClassA obj1 = new SomeClassA();
obj1.setSomeProperty("SomeClassA-object (directly created)");
System.out.println("## message=\"" + obj1.getSomeString() + "\"");
ClassPathXmlApplicationContext applicationContext;
applicationContext = new ClassPathXmlApplicationContext("/META-INF/package1_beans.xml");
applicationContext.setClassLoader(Thread.currentThread().getContextClassLoader());
SomeInterface obj2 = (SomeInterface) applicationContext.getBean("bean1");
System.out.println("## message=\"" + obj2.getSomeString() + "\"");
}
}
The /META-INF/package1_beans.xml being used reads:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans classpath:/org/springframework/beans/factory/xml/spring-beans-2.5.xsd">
<bean id="bean1" class="com.example.some_package_1.SomeClassA">
<property name="someProperty"><value>SomeClassA-object (created via Spring)</value></property>
</bean>
</beans>
The exception reads:
org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [com.example.some_package_1.SomeClassA] for bean with name 'bean1' defined in class path resource [META-INF/package1_beans.xml]; nested exception is java.lang.ClassNotFoundException: com.example.some_package_1.SomeClassA
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1141)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:524)
at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1177)
at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:758)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:422)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:380)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at com.example.test_spring_example.TestComponent.testOperation(TestComponent.java:71)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.tibco.amf.platform.runtime.componentframework.internal.proxies.operation.OperationHandler.invokeMethodWithThreadContext(OperationHandler.java:667)
at com.tibco.amf.platform.runtime.componentframework.internal.proxies.operation.AsyncToSyncOperationHandler.invoke(AsyncToSyncOperationHandler.java:98)
at com.tibco.amf.platform.runtime.componentframework.internal.proxies.ProxyInvocationHandlerRegistry$ProxyInvocationContext.invoke(ProxyInvocationHandlerRegistry.java:411)
at $Proxy67.invoke(Unknown Source)
at com.tibco.amf.binding.soap.runtime.transport.http.SoapHttpInboundEndpoint.processHttpPost(SoapHttpInboundEndpoint.java:565)
at com.tibco.amf.binding.soap.runtime.transport.http.SoapHttpServer.doPost(SoapHttpServer.java:195)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
at org.mortbay.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1213)
at com.tibco.governance.pa.amxcomponent.pep.http.HttpPepFilter.doFilter(HttpPepFilter.java:126)
at org.mortbay.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1205)
at com.tibco.amf.implementation.common.httpfilter.GenericComponentFilter.doFilter(GenericComponentFilter.java:65)
at org.mortbay.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1205)
at com.tibco.amf.hpa.tibcohost.jetty.internal.ConnectorFilter.doFilter(ConnectorFilter.java:49)
at org.mortbay.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1205)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:536)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:928)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:747)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:405)
at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.ClassNotFoundException: com.example.some_package_1.SomeClassA
at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:513)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:429)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:417)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at org.springframework.util.ClassUtils.forName(ClassUtils.java:211)
at org.springframework.beans.factory.support.AbstractBeanDefinition.resolveBeanClass(AbstractBeanDefinition.java:385)
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1138)
... 46 more
Actually, the solution turned out to be almost trivial!
As I already stated in my comment to #Robin apparently in OSGi the current thread's classloader and the current context or class' classloader are not the same!
So, all I had to do in the end was to set the current thread's context-classloader to the calling object's classloader and that's it! I.e. one doesn't even need to dig into OSGi to obtain the bundle's class loader or fiddle with manifests or POMs or anything like that - just tell Spring to use "my" own class' classloader and off you go!
...
// need to set the context class loader to "my" class loader to make Spring work:
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
ClassPathXmlApplicationContext applicationContext;
applicationContext =
new ClassPathXmlApplicationContext("/META-INF/package1_beans.xml");
SomeInterface obj2 = (SomeInterface) applicationContext.getBean("bean1");
System.out.println("## message=\"" + obj2.getSomeString() + "\"");
...
And - yes - one probably should set the thread's class loader back to the original value after that, just in case - so another good used for a try { ... } finally { ... } clause. :-)
Thanks all for responding!
M.
I have one other idea.
Instead of initializing your Spring context manually. Try adding this to your pom.xml (if you are using Maven):
<configuration>
<instructions>
<Spring-Context>spring/*.xml</Spring-Context>
Make it point to the location of your applContext. This seems a neater way to hook it up as well. If you are not using Maven youll need to add manually to the Manifest, Im not sure exactly the right syntax for that
Trying to implement a JAX-RS resource in Scala. My Java version of this has the following type signature:
#GET
#Path(value="echoold")
#Produces("application/json")
public Map<String,Object> get(
#QueryParam("param") String param,
#QueryParam("asOf") #DefaultValue(NOW) DateWrapper asOf,
#QueryParam("httpError") #DefaultValue("200") int httpError,
#QueryParam("httpErrorMessage") #DefaultValue("") String httpErrorMessage,
#QueryParam("fail") #DefaultValue("false") boolean fail) {
The Scala version is thus:
#GET
#Path(value="echo")
#Produces(Array("application/json"))
def get() = {
#QueryParam("param") param:String,
#QueryParam("asOf") #DefaultValue(NOW) asOf:DateWrapper,
#QueryParam("httpError") #DefaultValue("200") httpError:java.lang.Integer,
#QueryParam("httpErrorMessage") #DefaultValue("") httpErrorMessage:String,
#QueryParam("fail") #DefaultValue("false") fail:java.lang.Boolean):java.util.Map[String,Object] = {
When I start up my application, I get this strange error from RESTEasy (which I've formatted for readability):
org.jboss.resteasy.spi.InternalServerErrorException:
Bad arguments passed to
public java.util.Map opower.api.endpoint.echo.Echo.get(java.lang.String,
opower.api.support.DateWrapper,
java.lang.Integer,
java.lang.String,
java.lang.Boolean)
( java.lang.String someValue,
opower.api.support.DateWrapper opower.api.support.DateWrapper#28a34522,
java.lang.Integer 400,
java.lang.String This is the message,
java.lang.Boolean false )
The underlying exception is:
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:140)
Now, this class is configured via Spring, so it could be some crazy proxy class and it's getting messed up, but has anyone else seen something like this?
(If you don't know what RESTEasy/JAX-RS is doing, basically the container (RESTEasy) finds methods on classes that have those annotations on them, and then calls them when certain URL endpoints are hit)
I had the same with Spring/Scala and #Transactional method annotation.
needed to change proxy-target-class in
<tx:annotation-driven transaction-manager="txManager"
mode="proxy" proxy-target-class="true"/>
Default value for proxy-target-class is false. It requires cglib in classpath.
I guess mode="acpectj" might also work (didn't try)