I am currently migrating a Grails 2.4 project to Grails 3.0.10 or 3.1.0.M3.
In Grails 2.4, the following method is a workaround that allows me to detect whether a Domain Class features a composite primary key:
void isCompositePrimaryKey(GrailsDomainClass targetClass) {
def binder = new GrailsDomainBinder()
def idMapping = binder.getMapping(targetClass).identity
return idMapping instanceof org.codehaus.groovy.grails.orm.hibernate.cfg.CompositeIdentity
}
I cannot find a way to detect this in the Public API.
Though GrailsDomainClass still exists in the implementation source code, I cannot seem to access it from my project nor can I find the old CompositeIdentity.
An alternative strategy could be via targetClass.getIdentifier().getType()
but I cannot find any documentation on how to detect a composite key using the identity type.
Solved this simply by adding an additional explicit (non-transitive) dependency to build.gradle for the Hibernate 4 GORM implementation package.
(I determined the package and version by looking in the local gradle files cache but gradle dependencies would also have worked.)
Added to build.gradle:
compile 'org.grails:grails-datastore-gorm-hibernate4:5.0.0.RC2'`
This allows access to the internal API, then the above method still works.
NB. The GORM developers also advise that there is existing GORM API for this, via the PersistentEntity and MappingContext classes without using GrailsDomainClass.
Related
I'm recreating a working Grails 2.2.5 application in Grails 4 in order to get to know the new version (with the view to migrating all 2.2.x apps over in due course). So far I've only moved a handful of Groovy classes from the src directory over, but I'm running into a compile problem with a class which is apparently no longer present in Grails 4, org.codehaus.groovy.grails.commons.DefaultGrailsDomainClass. I use this to iterate through the persistent properties of a domain class (with persistentProperties). How would I do this in Grails 4? I.e., get all the persistent properties of a domain class?
DefaultGrailsDomainClass is indeed deprecated since Grails 3.3.2 in favor of the mapping context API. Fortunately, it is quite straightforward to replace the deprecated implementation.
Inject the grailsDomainClassMappingContext bean in your service or controller:
def grailsDomainClassMappingContext
then get the persistent entity by providing its name:
def entity = grailsDomainClassMappingContext.getPersistentEntity(domainObjName)
where domainObjName is a string and entity is an instance of org.grails.datastore.mapping.model.PersistentEntity. You can also get a specific property by using:
def property = entity.getPropertyByName(propertyName)
where propertyName is a string and property is an instance of org.grails.datastore.mapping.model.PersistentProperty.
The interfaces PersistentEntity and PersistentProperty offer a variety of useful methods to cover many uses.
(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
Please note: Although my specific question at hand involves the Grails Shiro plugin, I believe this to be a core Grails question at heart. And so any battle weary Grails veteran should be able to answer this, regardless of their experience with Grails Shiro.
Using the Grails Shiro plugin (via grails shiro-quick-start) produces a Shiro realm class under grails-app/realms. For instance, running:
grails shiro-quick-start --prefix=com.example.me.myapp.Mongo
...will produce:
myapp/
grails-app/
realms/
com/
me/
myapp/
MongoDbRealm.groovy
Where MongoDbRealm is the Shiro realm.
package com.example.me.myapp
class MongoDbRealm {
FizzClient fizzClient // How to inject?
BuzzClient buzzClient // How to inject?
FooFactory fooFactory // How to inject?
// lots of auth-centric, generated code here...
}
Let's pretend that MongoDbRealm is very complicated and needs to be injected with lots of complicated objects such as service clients and factories, etc. How do I properly inject MongoDbRealm?
Will #PostConstruct work here? Can I inject Grails services into it like I do with controllers? Something else?
Again, I would imagine that dependency injection works the same here (with Grails Shiro and my MongoDbRealm) as in any other class defined under grails-app. I just don't understand how grails-app/* dependency injection works.
Plugins that support defining classes under grails-app typically do so by defining a new type of artifact, and specify an ArtefactHandler implementation to manage that. The Grails ArtefactHandlerAdapter class implements that interface and provides a lot of common functionality, so that's often used, and is used in the plugin's RealmArtefactHandler class.
Dependency injection would be configured in the newInstance method. You can see where I did this for one of my plugins here. Since the Shiro plugin doesn't override that method from the base class, it looks like dependency injection isn't supported.
Note that using #PostConstruct (or implementing InitializingBean) would work if the realm classes were registered as Spring beans, but it doesn't look like that's the case in this plugin.
I try to avoid using the Holders class since in most cases it's straightforward to use DI instead of pulling in dependencies explicitly, but it looks like you will need to use that approach here, e.g. fizzClient = Holders.applicationContext.fizzClient (assuming that is registered as the "fizzClient" bean).
We're using the Grails spring security plugin:
http://grails.org/plugin/spring-security-core
I simply want to change the default access decision manager from the default AffirmativeBased to UnanimousBased. I do not see it documented anywhere in the plugin manual:
http://grails-plugins.github.io/grails-spring-security-core/docs/manual/
Does anyone know if it's possible to change this?
I added one additional voter, "myVoter" which is detected and working fine.
grails.plugins.springsecurity.voterNames = [
'myVoter', 'authenticatedVoter', 'roleVoter',
]
Based on Burt Beckwith's "Hacking the Grails Spring Security Plugin" [http://www.slideshare.net/gr8conf/hacking-the-grails-spring-security-plugins], it should be possible to simply provide a different implementation of the accessDecisionManager bean. Something like this:
accessDecisionManager(org.springframework.security.access.vote.UnanimousBased)
in resources.groovy
When I tried this, I had trouble with the constructor syntax in the bean definition. The access decision manager wants a list of voters in the constructor and I couldn't quote figure out how to get my voters defined in config.groovy as parameters to the constructor. I was about to derive my own decision manager (with parameterless constructor) from UnanimousBased when I stumbled upon the source code for AuthenticatedVetoableDecisionManager in the Grails Spring Security Plugin. This class splits the voters in half... anything deriving from AuthenticatedVoter will immediately fail if any are denied (e.g. AUTHENTICATED_FULLY family), but all other voters will pass if any are granted (e.g. RoleVoter). I wanted the AuthenticatedVoter functionality for my custom voter so I simply derived from AuthenticatedVoter (making sure to override all of the interface methods so I didn't accidentally get any base class functionality) and stuck with the default decision manager.
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.