FacebookConnect Plugin

FacebookConnect v0.1 plugin fails to load in production WAR file because of file-not-found exception for FacebookConnectConfig.groovy

Details

  • Type: Bug Bug
  • Status: Resolved Resolved
  • Priority: Blocker Blocker
  • Resolution: Fixed
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None
  • Environment:
    Windows XP, Tomcat 6.0.18, JDK 1.6.03

Description

I installed the Facebook Connect v0.1 plugin for my Grails application and it works fine when using the built-in Jetty web server (i.e., "grails run-app" from within my project root). However when I created a WAR file ("grails war") and deployed it against Tomcat (v6.0.18) the application fails to start with this error:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flowRegistry': Cannot resolve reference to bean 'flowBuilderServices' while setting bean property 'flowBuilderServices';
...
nested exception is Error creating bean with name 'facebookConnectService': Invocation of init method failed; nested exception is java.io.FileNotFoundException: C:\webservers\apache-tomcat-6.0.18\bin\grails-app\conf\FacebookConnectConfig.groovy (C:\webservers\apache-tomcat-6.0.18\bin\grails-app\conf\FacebookConnectConfig.groovy)
at java.security.AccessController.doPrivileged(Native Method)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3843)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4342)
...
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)

Further investigation into the code of FacebookConnectConfig.groovy shows that in the afterPropertiesSet() method it attempts to load a file from a location which is inexistent in the WAR file:

FacebookConnectService.groovy, lines 14-19:

void afterPropertiesSet() { GroovyClassLoader loader = new GroovyClassLoader(getClass().getClassLoader()) //Class clazz = loader.parseClass(new File("src/templates/_FacebookConnectConfig.groovy")) Class clazz = loader.parseClass(new File("grails-app/conf/FacebookConnectConfig.groovy")) facebookConnectConfig = new ConfigSlurper().parse(clazz) }

The correct way would be to perform a check for the existence of the compiled Java class FacebookConnectConfig, which will be available in the WEB-INF/classes of the generated WAR file. Something like:

void afterPropertiesSet() {
// check if there is a compiled class for the Facebook connect config groovy script
// this will be the case when an application is bundled in a WAR
def config = new FacebookConnectConfig()
if (config != null) { // compiled config class found, we must be running as a WAR facebookConnectConfig = config } else { // no compiled class exists for the config, we must be running the Grails built-in web server GroovyClassLoader loader = new GroovyClassLoader(getClass().getClassLoader()) Class clazz = loader.parseClass(new File("grails-app/conf/FacebookConnectConfig.groovy")) facebookConnectConfig = new ConfigSlurper().parse(clazz) }
}

I've attached the modified FacebookConnectService class in case it's helpful.

Activity

Hide
Daniel Bloomfield Ramagem added a comment -

Oops, the code I posted with the correction is missing one line. Here it is in full again:

void afterPropertiesSet() {
// check if there is a compiled class for the Facebook connect config groovy script
// this will be the case when an application is bundled in a WAR
def config = new FacebookConnectConfig()
if (config != null) { // compiled config class found, we must be running as a WAR facebookConnectConfig = new ConfigSlurper().parse(config.getClass()) } else { // no compiled class exists for the config, we must be running the Grails built-in web server GroovyClassLoader loader = new GroovyClassLoader(getClass().getClassLoader()) Class clazz = loader.parseClass(new File("grails-app/conf/FacebookConnectConfig.groovy")) facebookConnectConfig = new ConfigSlurper().parse(clazz) }
}

Show
Daniel Bloomfield Ramagem added a comment - Oops, the code I posted with the correction is missing one line. Here it is in full again: void afterPropertiesSet() { // check if there is a compiled class for the Facebook connect config groovy script // this will be the case when an application is bundled in a WAR def config = new FacebookConnectConfig() if (config != null) { // compiled config class found, we must be running as a WAR facebookConnectConfig = new ConfigSlurper().parse(config.getClass()) } else { // no compiled class exists for the config, we must be running the Grails built-in web server GroovyClassLoader loader = new GroovyClassLoader(getClass().getClassLoader()) Class clazz = loader.parseClass(new File("grails-app/conf/FacebookConnectConfig.groovy")) facebookConnectConfig = new ConfigSlurper().parse(clazz) } }
Hide
Daniel Bloomfield Ramagem added a comment -

Correct version of fixed FacebookConnectService.groovy

Show
Daniel Bloomfield Ramagem added a comment - Correct version of fixed FacebookConnectService.groovy
Hide
Yun Zhi Lin added a comment -

I also got the same "FacebookConnectConfig.groovy" FileNotFound exception running app-engine plugin alongside with facebook-connect.

The "app-engine run" seems to be running local server using expanded compiled classes stage/WEB-INF/classes directory. So in the end I was able to use your Daniel's workaround to pick up the FacebookConnectConfig from the classpath. A minor different is I used:

def config = Class.forName("FacebookConnectConfig").newInstance()

To overcome IDE compilation warnings. It would be good if the author could check in this fix and releases it with the next build.

Show
Yun Zhi Lin added a comment - I also got the same "FacebookConnectConfig.groovy" FileNotFound exception running app-engine plugin alongside with facebook-connect. The "app-engine run" seems to be running local server using expanded compiled classes stage/WEB-INF/classes directory. So in the end I was able to use your Daniel's workaround to pick up the FacebookConnectConfig from the classpath. A minor different is I used:
def config = Class.forName("FacebookConnectConfig").newInstance()
To overcome IDE compilation warnings. It would be good if the author could check in this fix and releases it with the next build.
Hide
Seymour Cakes added a comment -

I took the liberty to apply the patches submitted and release a new version – 0.2 – because this problem is effecting my production project and I feel many will benefits from this patch.

Show
Seymour Cakes added a comment - I took the liberty to apply the patches submitted and release a new version – 0.2 – because this problem is effecting my production project and I feel many will benefits from this patch.

People

Vote (8)
Watch (4)

Dates

  • Created:
    Updated:
    Resolved: