In a Spring XML configuration, I have the followings:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
....
</bean>
and in a Java class, I have
#Autowired
private SessionFactory sessionFactory;
without a setter. That works.
Now, I change the sessionFactory to a Java configuration as the followings.
#Configuration
#EnableTransactionManagement
#PropertySource({ "classpath:jdbc.properties" })
public class PersistenceConfig {
#Bean
public SessionFactory sessionFactory() {
LocalSessionFactoryBuilder lsfb = new LocalSessionFactoryBuilder(dataSource());
lsfb.addAnnotatedClasses(...);
lsfb.setProperties(hibernateProperties());
return lsfb.buildSessionFactory();
}
// ...
}
And I get an error "could not autowire field". Adding a setter doesn't help. Why the sessionFactory can't get autowired with a Java configuration?
BTW, I can work around this problem by having a Java configuration for the DAO as well.
I see that there is no #ComponentScan annotation on your #Configuration class, so probably the problem is in how you import this configuration. Please ensure that all particular beans live in the same context or at least that PersistenceConfig is parent to the context in which you are autowiring SessionFactory
I have added the #ComponentScan annotation and it doesn't solve the problem. The annotation tells Spring to look for any #Components to configure as beans. This problem seems to me is that during the process of creating a bean with #Component, it can't find a bean configured in my Java configuration file which is started in WebAppInitializer.
Related
I am using websphere liberty 19.0.0.8 and I wanted to use Jersey instead of default CXF for jax-rs implementation. I removed jaxrs-2.1 feature from server xml and packaged jersey implementation jars in my webapp .war.
<featureManager>
<feature>servlet-4.0</feature>
<feature>jndi-1.0</feature>
<feature>requestTiming-1.0</feature>
<feature>monitor-1.0</feature>
<feature>localConnector-1.0</feature>
<feature>restConnector-2.0</feature>
<!-- Do not add enabled webProfile-8.0 because we want to disable default
REST implementation (Apache-CXF) provided by Liberty. We want to use Jersey
as our REST implementation because it better support multi-part streaming, -->
<!-- <feature>webProfile-8.0</feature> -->
<feature>jsp-2.3</feature>
<feature>cdi-2.0</feature>
<feature>managedBeans-1.0</feature>
<feature>jdbc-4.2</feature>
<!-- <feature>jaxrs-2.1</feature> -->
</featureManager>
Gradle build including jersey implementation
//JxRS Jersey implementation
compile group: 'org.glassfish.jersey.containers', name: 'jersey-container-servlet', version: '2.25.1'
compile group: 'org.glassfish.jersey.media', name: 'jersey-media-json-jackson', version: '2.25.1'
compile group: 'org.glassfish.jersey.media', name: 'jersey-media-multipart', version: '2.25.1'
compile group: 'com.fasterxml.jackson.jaxrs', name: 'jackson-jaxrs-json-provider', version: '2.9.0'
Extended jersey's ResourceConfig to configure my RestApplication
#ApplicationPath("/")
public class RestApplicationConfig extends ResourceConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(RestApplicationConfig.class);
public RestApplicationConfig() {
super();
configureResourcesAndFeatures();
}
private void configureResourcesAndFeatures() {
packages(RestApplicationConfig.class.getPackage().getName());
register(MultiPartFeature.class);
}
}
With all this setup my rest api works and I am able to make use of Jersey's multiple related classes in my code.
Now the problem is with CDI. In my resource class I am able to inject CDI managed resource/classes for example
#ApplicationScoped
#Path("/ping")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public class PingResource {
private static final Logger LOGGER = LoggerFactory.getLogger(PingResource.class);
#Resource(lookup = "jndi_dpa_iss_rest_url")
private String issRestBaseUrlInResource;
#Inject
private DocumentService documentService;
}
In above class #Resource and #Inject are not able to resolve JNDI resource and managed bean. As soon as I enable jaxrs-2.1 feature in server.xml CDI injection works but then I loose jersey, it uses CXF.
DocumentService and its implementation class is defined as below. Everything is under same package as RestApplicationConfig class or it's sub-packages.
#ApplicationScoped
#Transactional(value = Transactional.TxType.NOT_SUPPORTED)
public class DocumentServiceImpl implements DocumentService {
// some code here
}
What do I need to use CDI in my rest resource classes?
Because there is no jersey extension for CDI 2.0 at the moment, I had to find workaround. Workaround is to manually query CDI container to the the type of bean we are interested in. This way we are manually injecting CDI bean in our resource class but the injected bean is managed bean instance so CDI has taken care of satisfying all its dependecies.
This we we are doing manual injection only in Resource layer but CDI should work fine for layer down.
Working code.
#ApplicationScoped
#Path("/ping")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public class PingResource {
private DocumentService documentService = CDI.current().select(DocumentService.class).get();
}
Basically instead of #Inject manually query CDI container.
I am having issues with dependency injection in a batchlet.
#Named
public class SimpleBatchlet extends AbstractBatchlet {
#Inject
protected StorageService storageService;
...
public String process() throws Exception {
storageService.doSomething(); // this throws a null pointer exception
}
}
#Named
public class LocalFileStorageService implements StorageService {
public void doSomething() {
}
}
I have tried putting beans.xml in both META-INF and WEB-INF and removing it, all to no avail. I also tried changing the scopes of the beans to singletons, etc. I am invoking / starting the batch job through the use of an #Schedule annotation on a method that uses BatchRuntime to start the job.
I must be missing something simple as I know this should work. The actual scope of the beans I will use may need to vary, but the point I am trying to make is that I don't believe bean scope is a problem, but some other configuration issue.
I should also note that I only have 1 implementation of StorageService.
Not clear what really is your problem (NPE on injected CDI bean?), but annotating your Batchlet #Dependent should solve the problem :
#Named
#Dependent
public class SimpleBatchlet extends AbstractBatchlet {
#Inject
protected StorageService storageService;
}
Batchlet need to be #Named and #Dependent for integration with CDI.
I have the structure described below, but I cannot make it so MyWebService has its member myService not null. The code of MyWebService is properly executed when I call the webservice. When I look at the JBoss logs, I keep seeing that MyServiceBean has several JNDI bindings allocated to it.
So how do I bind MyServiceBean to MyWebService?
Thanks!
my-ejb.jar:
#Local
public interface MyServiceBeanLocal {
...
}
#Stateless
public class MyServiceBean implements MyServiceBeanLocal {
...
}
my-web.war:
#Webservice(...)
public class MyWebService {
#EJB
MyServiceBeanLocal myService;
...
}
my-ear.ear:
* my-ear.ear
|-* my-web.war
|-* my-ejb.jar
Have you tried using MyServiceBeanLocal as a Remote interface ? You are trying to use dependency injection from a Web module and for a Local Interface .This is not actually suggested. Anyway, At first try to make the interface #Remote . If still it doesn't work try to use`Remote Look up from the Web module for your Remote interface link
I use CXF. CXF is not an EJB container, hence the issues I got.
I had to manually bind the EJBs, using their full name.
env: JBoss 7.1.1, jdk 1.7, WELD module upgraded to 1.1.10(just in case)
I have a JPA project that I am adding to the WEB-INF\lib directory. It contains my entities and DAO objects, which has the Entity Manager inject. I'm using custom annotations to qualify the PersistenceContext, which is Produced in a Resources class. I've run Arquillian tests in this project to ensure it works.
I have a beans.xml file in the \META-INF\ directory of the JPA jar and in the \WEB-INF\ directory of the war file. I even printed it out and put it on my desk, still didn't help.
Within my war file I have a class that is injecting a DAO object from the JPA jar. Its not working, its null.
I've found examples from the jboss (without jpa jar) with CDI and it works.
I've looked for examples but cannot find any with a jpa jar. Can anyone point me to where there is an example of a jee6 web app, with a JPA utility jar, that uses annotations to inject something from the JPA jar into the war classes?
Thank you very much for reading this plea.
--------------------additional info-----------------
structure of war file
META-INF
->maven
-->com.xyz
--->web
---->pom.properties
---->pom.xml
->MANIFEST.MF
WEB-INF
->classes
->lib
-->entities.jar
->beans.xml
->faces-config.xml
->web.xml
stack trace:
22:23:12,011 INFO [org.quartz.core.JobRunShell] (DefaultQuartzScheduler_Worker-2) Job DEFAULT.extractDir threw a JobExecutionException: : org.quartz.JobExecutionException: java.lang.NullPointerException [See nested exception: java.lang.NullPointerException]
at com.xyz.asp.commsrv.scheduler.jobs.DirScanJob.execute(DirScanJob.java:149) [classes:]
at org.quartz.core.JobRunShell.run(JobRunShell.java:213) [quartz-2.1.7.jar:]
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:557) [quartz-2.1.7.jar:]
Caused by: java.lang.NullPointerException
at com.xyz.asp.commsrv.scheduler.jobs.DirScanJob.execute(DirScanJob.java:140) [classes:]
... 2 more
This is the class that has the DAO object injected. This is a quartz scheduler job which is started by a ServletContextListener during jboss startup:
#DisallowConcurrentExecution
#PersistJobDataAfterExecution
public class DirScanJob implements Job{
...
#Inject
FiletracksentHome ftsHome;
#Override
public void execute(JobExecutionContext context) throw JobExecutionException{
...
BigDecimal bd = ftsHome.nextId()
}
}
This class resides in entities.jar:
#Stateless
public class FiletracksentHome{
#Inject
#DatabaseEntities
private EntityManager entityManager;
public BigDecimal nextId(){
...
}
}
CDI is available in the ServletContextListener but nothing within the context of the Quartz Scheduler. I didn't want to bother with another library, since CDI wasn't necessary. I injected some properties that I needed using the #Resource annotation within the ServletContextListener implementation ...
#Resource(lookup = "java:app/env/quartzjobdirectory")
private String quartzJobDirectory;
and within the web.xml ...
<env-entry>
<description>Quartz Jobs Directory</description>
<env-entry-name>java:app/env/quartzjobdirectory</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>/appl/jboss-as-7.1.1.Final/standalone/configuration/quartz_jobs/</env-entry-value>
</env-entry>
And for the EJB calls within the Quartz Jobs because DI is not available I did some JNDI calls, such as ...
InitialContext ic = new InitialContext();
readyDocs = (ReadyDocumentsLocal) ic.lookup("java:global/commsrv-ear-1.0.0/commsrv-ejb-1.0.0/ReadyDocumentsBean!com.ista.asp.commsrv.ReadyDocumentsLocal");
and the EJB ...
#Stateless
public class ReadyDocumentsBean implements ReadyDocumentsLocal {
...
}
FYI ... jboss as 7.1 will output to the server.log the JNDI bindings for session beans.
I am trying to integrate JCache from Infinispan into my existing EJB project.
I have added Infinispan 5.0.1 CDI and Core packages to Maven pom.
Added Infinispan Interceptors in beans.xml and able to use the CacheResult annotation.
I am deploying the app in Glassfish 3.1.1. I have checked the Weld jar version, which is
Module : org.jboss.weld.osgi-bundle:1.1.1.Final
In the runtime, the CacheResult Method interceptor is not caching the method result and its always called.
My code looks like this,
public void cacheTest() {
Thread.currentThread().setContextClassLoader(
this.getClass().getClassLoader());
EmbeddedCacheManager manager = createCacheConfig();
Set<String> cacheList = manager.getCacheNames(); // new
// DefaultCacheManager().getCacheNames();
for (String cache : cacheList) {
System.out.println("Cache name " + cache);
}
defaultCache = manager.getCache("test-cache");
defaultCache.put("aa", "AA");
String user = "User";
greet(user);
Set<String> keys = defaultCache.keySet();
for (String key : keys) {
System.out.println("Key is -" + key + "Value is -"
+ defaultCache.get(key));
}
}
#CacheResult(cacheName = "test-cache")
public String greet(#CacheKeyParam String user) {
user += "Hello";
return user;
}
public EmbeddedCacheManager createCacheConfig() {
EmbeddedCacheManager manager = new DefaultCacheManager();
Configuration conf = new Configuration();
conf.fluent().eviction().strategy(EvictionStrategy.FIFO).maxEntries(10)
.expiration().maxIdle(1200000L).build();
conf.fluent().clustering().sync();
manager.start();
manager.defineConfiguration("test-cache", conf);
return manager;
}
greet() method gets called but it will never add the method result to the test-cache. I feel am I missing some configuration or...I dont know. Please help me on this.
when I Inject the classes, they wont get constructed and they are null. The code is like this,
#Inject
private static org.infinispan.Cache<String, String> defaultCache;
#Inject
private static EmbeddedCacheManager defaultCacheManager;
These gets executed without any error, but they wont get initialized.
I have no clue...But I am able to inject other EJBs with in this class easily. By the way I am trying to add Jcache functionality in one of EJBs.
I would appreciate your help...
Thanks...
Raj S
Your greet method is in a CDI bean or in an EJB, right?
The cache defined in JCache annotations is looked up in the cache manager provided by Infinispan CDI. This cache manager contains the cache configured with CDI (for more information, see https://docs.jboss.org/author/display/ISPN/CDI+Support). In your example the test-cache configuration will have no effect.
Another thing, if your cacheTest and greet methods are in the same class the greet method cannot be intercepted. If that's not the case maybe you're hitting GLASSFISH-17184.
For the Cache and EmbeddedCacheManager injections the problem is that you're doing a static injection, not supported by CDI. From CDI (JSR-299) specification
An injected field is a non-static, non-final field of a bean class, or of any Java EE component class supporting injection.
If your method result is not cached, I think it's because the CacheResultInterceptor is not called. I've just made the test with the Infinispan CDI quickstart. If the interceptors are in a lib they are not enabled. I think it's a bug in Glassfish.
Btw, you can see an example of code in the Infinispan CDI quickstart here.
Hope this help!