Java EE injection not working on Glassfish - dependency-injection

(Please be kind, these are my first steps in Java EE).
I'm working with Netbeans 8.1, deploying an EJB module on a local Glassfish Server.
I have a glassfish-resource.xml with the following resource defined:
<jdbc-resource enabled="true" jndi-name="java:app/jdbc/myDataSource"
And I have a DAO class where I'm trying to inject that resource
#Named
public class SimpleDal {
#Resource(name = "jdbc/myDataSource", lookup = "java:app/jdbc/myDataSource")
private static DataSource ds ;
I have tried several ways to make this work but I always end up with NULL in the variable ds. I've been debugging and querying the Context, and I always end up with the name java:app/jdbc/myDataSource not found.
Maybe I'm not doing something right, this is my first steps on Java EE (I've always developed for PHP). Can somebody please direct me in order to avoid losing more time? Thanks
Note: I've add the #Named annotation to the SimpleDal class because I've read somewhere that in order to Injection to work, I have to be on a Bean.

So, after some time I finally found out that injection doesn't work reliably on static fields (at least on my setup). Changed the field to an instance field and It worked . Posting this answer for anyone who is facing the same situation

Related

How to get and cast JNDI object correctly in Liberty

I have a big problem on getting the correct instance or at least casting the instance I got with JNDI-lookup to correct interface at Web Sphere Liberty (16.0.0.4, running on Java 7, though using Oracle Java 1.8.0_45 in the back, developing on Eclipse Neon.2).
When I start the server and the ear containing the EJB, I get the following notification into the log:
The server is binding the xxx.interfaces.MyLocal interface of the MyEJB enterprise bean in the xxx-ejb.jar module of the xxx-ear application. The binding location is: java:global/xxx/MyEJB!xxx.interfaces.MyLocal
Then I have a web application (ear) which has a service provider (with #Produces) for the previously started ejb-service, which will provide the JNDI resource as injectable (#Inject) for the rest of the application (a bit tricky thing, the main idea is to allow to change the lookup location from configuration file + do some other stuff also). It seems to work correctly for all it is supposed to, but when getting the JNDI-resource, it kind of works but not correctly.
If I put the ejb part as a dependency into my web-module, I can inject it directly (#Inject MyLocal myEjb;).
As the injected resource I get an object with the signature:
EJSMyLocal0SLMyEJB_a4549339#cc5d2cdd
with lookup I get an object with signature (at the same time as the inject):
EJSMyLocal0SLMyEJB_a4549339#cdda36a7
(Not the same instance afaik, but the "type" is correct?)
The injected resource is correctly (automatically of course) cast on 'MyLocal' interface and is ok.
When I try to check the resource got with JNDI, it does not qualify as an instance of 'MyLocal' nor as 'MyRemote'? Also the actual cast fails of course with ClassCastException. (MyRemote is basically the same as the MyLocal interface ... MyLocal extends MyRemote, both interfaces are accordingly annotated with #Local and #Remote)
The EJB looks like this at the time of testing...
#Stateless
#Named
#Default
#Local(MyLocal.class)
#Remote(MyRemote.class)
public class MyEJB implements MyLocal, MyRemote { ... }
I also tried to cast the JNDI resource like this.
InitialContext ic = new InitialContext();
Object lookedUpEjb = ic.lookup(lookup); // the 'java:global...' from log
MyRemote jndiEjb = (MyRemote) PortableRemoteObject.narrow(lookedUpEjb, MyRemote.class)
// Tried also casting/checking 'instanceof' to MyLocal...
No difference with that, the same ClassCastException occurs?!
I have the following features in server.xml
<featureManager>
<feature>javaee-7.0</feature>
<feature>ldapRegistry-3.0</feature>
<feature>localConnector-1.0</feature>
<feature>adminCenter-1.0</feature>
<feature>wsSecurity-1.1</feature>
<feature>ejbLite-3.2</feature>
<feature>ejbRemote-3.2</feature>
<feature>cdi-1.2</feature>
<feature>jpa-2.1</feature>
<feature>jsf-2.2</feature>
<feature>jaxrs-2.0</feature>
<feature>jaxws-2.2</feature>
</featureManager>
I found this documentation on the Liberty JNDI functionality:
https://www.ibm.com/support/knowledgecenter/SSAW57_liberty/com.ibm.websphere.wlp.nd.multiplatform.doc/ae/twlp_ejb_remote.html
I can't see where I go wrong. How do I cast that object from JNDI lookup to MyLocal or MyRemote interfaces?
---- Note ----
Using the #EJB annotation is not an option (it works though), since it will be hard coded reference to the resource. I want it to be optional though, thus JNDI lookup. #EJB will cause the app to crash when the resource is not available.
The problem is that each application has a different ClassLoader and the object that has been bound into JNDI was loaded with the ClassLoader of the application that defined the EJB.
This should not be an issue for Remote EJB interfaces as the ORB should have taken care of this for you. On a remote call that returns such an object, the ORB will serialize the object (from the target ClassLoader) and then deserialize using the client ClassLoader. For a lookup like this, the PortableRemoteObject.narrow should also take care of this. The failure here appears to just be a bug in the ORB.
In order to support cross application access to Local EJB interfaces, either the Local EJB interface needs to be moved to a shared library, that is used by both applications, or both applications configured to use a single global ClassLoader. See this link for more information about using Local EJB interfaces across applications: Correct way to lookup local EJB in websphere - Getting ClassCastException (Note: this link is discussing traditional WebSphere, but the issue is the same with Liberty, as is the resolution to use a shared library for the interface).

Grails 3.X Inject service into Custom Listener

i wonder if someone knows hot to inject a service into a custom listener in Grails 3.X. I'm working with spring secuirty plugin in order to avoid brut force attacks. There is one answer but for Grails 2.0. Thanks in advance.
UPDATE !
Just for those who can use it . I tried Autowired and it works. Something like:
#Autowired
public LoginAttemptService loginAttemptService
The LoginAttemptService is already declared as a Bean
As shown here
Declare it like your injection:
MyService myService
Then when needed
def ctx = Holders.applicationContext
myService= ctx.myService
Alternatively
def myService = Holders.grailsApplication.mainContext.getBean('myService')
The alternate method is particulary useful for src/main/groovy calls if required to a service
Think their both the same thing in different ways

Grails access Config properties in Secured annotation

I am trying to access the Config of the grails application via the #Secured annotation of spring security with the aim to externalize the role name later.
Sadly, I wasn't able to get this working. Neither by trying to use deprecated ConfigurationHolder class nor getting reference to grailsApplication object.
import org.codehaus.groovy.grails.commons.ConfigurationHolder as CH
#Secured([CH.config.grails.app.user])
class MyController { ...}
Config.groovy:
...
grails.app.user = "ROLE_APPNAME_USER"
...
Does anyone have an advice how to solve this?
EDIT
Came across Burt's article which was informational.
You can't - annotation element values must be compile-time constants because they're resolved by the compiler and stored as part of the class bytecode.
You may have more luck using one of the other mechanisms to specify security constraints (static rules or Requestmap instances in the database) instead of annotations.

Using CDI to inject a Data Access Object

Assuming I have a data access object that I've already written, I'd like to be able to use CDI to inject that into say, a service class. Furthermore, I have two implementations of that DAO.
My understanding of CDI is that I'd have to annotate my DAO implementation class so that CDI would know which implementation to inject.
The problem is, the DAO is in a .jar file. By annotating it with CDI annotations, I'm using JavaEE imports in a non-JavaEE class.
For example, let's say I have the following class
public class BusinessService {
#Inject #SomeMybatisQualifier AccountDAO accountDao;
...
}
The #Inject annotation comes from javax.inject.Inject. Now, this service class is dependent on a JavaEE environment.
Can someone please explain to me what I'm missing? How do I inject a non-annotated class into another non-annotated class? This is fairly simple with Spring.
I agree with LightGuard if there's enough classes. But for a couple, why not just produce them with #Produces?
Here's a decent example of implementing your own producer:
Depedency inject request parameter with CDI and JSF2
You should be able to write return new MyObject(); and you can add whatever qualifiers you want
Not sure what's unclear but here's the gist of things: For CDI to scan a jar for beans it must have a beans.xml. Else it will not be scanned and thus not available for injects.A String is not available either. If you try to inject a String say;
#Inject
String myString;
CDI will have no clue what to give you just like your jar. But I know what String I want (a requestparam) and I can let CDI know as well. How? Well I supply a qualifier #RequestParam to my producer (see example again) and now when I want to use it in client code I do it like this:
#Inject
#RequestParam
String myString;
You can do the same thing. Have a producer and just create a new instance of whatever you need and then return it. Now CDI will know just how to dependency inject that particular bean.
Now say you have 40 classes. Then it gets messy to produce them and you want to make sure it gets scanned instead. Then you write your own little extension, observe when CDI is about to scan and instruct it to scan additional jars. Such extension is probably easy to write but I don't know the details because I have not written any extensions like it
By far, the easiest thing would be to create a CDI extension to add the classes in the jar (because there's no beans.xml in that jar so it won't be picked up by CDI) and add additional qualifiers to the metadata.

Using resources.groovy to define services

I'm using the resources.groovy to declare a service e.g.
aService(com.foo.OrganizationService)
so that I can tie aService to my controllers instead of using organizationService which could change in the future.
I've noticed that the OrganizationService doesn't get treated special like other services "not" declared in the resources.groovy. For example it doesn't get injected with grailsApplication, and likely a hibernateSession etc and other things I've not hit yet....
Now, I know I can manually wire in stuff to my service but I'd rather not have to maintain that...
Is there a special way to declare a service in the resources.groovy so that gets treated like another service that grails loads up?
TIA
The short answer to your question is "no".
Under the covers, Grails services are driven by some intelligent code that is referencing a specific location and expecting certain properties.
Viewing the source code (especially around the ServicesGrailsPlugin.groovy) is a good way to see the "magic" in how these are wired together.
Is there a reason you wouldn't want to use a bonafide Grails service to solve your problem? If you are expecting things like a grailsApplication, it seems like that use is pretty specific to Grails and would be a good candidate for porting over to a "true" Grails service.
Good luck!
So I've come full circle on this. This is a timing problem. Where services haven't been grails initialized yet.
Basically when you use the resources.groovy to do service wiring you run the risk of using a Service that might initialize itself e.g. afterPropertiesSet method or static initializers that use grails services (log, hibernate session, ..) that haven't been injected yet.
So... What I've turned to instead is to create my own BeanBuilder in a BootStrap.groovy file.
BeanBuilder builder = new BeanBuilder(grailsApplication.parentContext)
def bb = builder.beans {
LoginListener(com.foo.LoginListener) {
springSecurityService = ref("springSecurityService")
userService = ref("userService")
}
}
bb.registerBeans(grailsApplication.mainContext)

Resources