Grails 4 : Database Migration plugin issue - grails

Since upgrading to Grails 4, the migration scripts do not appear to be getting loaded from where they are configured. This results in the following error;
liquibase.exception.ChangeLogParseException:
java.lang.IllegalArgumentException: Script text to compile cannot be
null!
Up to now, I had only specified the location on gradle config;
sourceSets {
main {
resources {
srcDir 'grails-app/migrations'
}
}
}
I have since added the additional config provided by the plugin but to no avail;
grails.plugin.databasemigration.changelogLocation = 'grails-app/migrations'
Through debugging, I can see that the grails-app/migrations path does not appear to be added to the list of locations but also discovered that grails-app/conf is, so I temporarily dropped them all in there and voilĂ ... the application fired up.
Anyone know if this is a know issue with the plugin or some missing config?

As indicated in the github issue comment here, the sourceSets declaration in the gradle config file must be above the dependencies declaration.

Related

Log4j2 not loading log4j2.xml

I have a problem concerning log4j2 which does not load the log4j2.xml configuration file in a project.
The project is bundled into an uber jar file. When running the application using java -jar jarfile.jar the application starts but log4j prints the following error to the console:
ERROR StatusLogger No log4j2 configuration file found. Using default
configuration: logging only errors to the console.
I checked the jar and it definitely contains a log4j2.xml file in the root location.
Because I could not figure out why this does not work I debugged to log4j2 bootstrap code. I found out that log4j never tries to read the log4j2.xml. This should happen in org.apache.logging.log4j.core.config.ConfigurationFactory.Factory#getConfiguration.
Unfortunately the list of factories used in this method is empty thus the method always returns null.
Any ideas on this?
If you want to check this clone https://github.com/cryptomator/cryptomator, cd to the main directory in the cloned repo and run mvn clean install -DskipTests -P uber-jar afterwards you will find the jar file in question under main/uber-jar/target.
I suspect this is the same issue as Log4j2 configuration not found when running standalone application builded by shade plugin since it sounds like you are building an uber jar.
I have a similar issue, but not using shade.
I have a jar file, with dependencies in /lib
I have a log4j2.xml file in the same location as the main jar file.
I can (obviously) run the jar file by calling:
java -Dlog4j2.configurationFile=.\log4j2.xml -jar myjar.jar
However, in Windows, it's possible simply to double-click the jar file to load it. Everything loads and works, except that it doesn't find the log4j2.xml file - so no logfile is written.
What I would like to be able to do is have a simple jar file I can hand to someone and have it run on their machine, with the ability to configure logging in the event they run into issues.
EDIT:
To do that, you need to amend your code thus:
public class MyClass
{
static
{
System.setProperty("log4j.configurationFile", "log4j2.xml");
}
private final static Logger LOG = LogManager.getLogger();
//OTHER STUFF HERE
}
Thanks to Load Log4j2 configuration file programmatically for the answer.

Resources plugin with cached-resources

Grails 2.3.7 and the cached resources plugin, at least with lesscss resources are not working properly.
The cached plugin returns an erro which is the same error as described in this thread:
<dt>Class</dt><dd>java.lang.NullPointerException</dd><dt>Message</dt><dd>Cannot invoke method cache() on null object</dd></dl><h2>Around line 31 of <span class="filename">grails-app/resourceMappers/org/grails/plugin/cachedresources/HashAndCacheResourceMapper.groovy</span></h2>
<pre class="snippet"><code class="line"><span class="lineNumber">28:</span> if (log.debugEnabled) {</code><code class="line"><span class="lineNumber">29:</span> log.debug "Setting caching headers on ${req.requestURI
http://grails.1312388.n4.nabble.com/Grails-resources-bug-Unable-to-load-resources-at-startup-td4652307.html
The problem is that cacheHeadersService is not injected or null in the cacheheaders plugin.
Trying to solve this I copied the contents of the cached-resources-plugin 1.1 from target/work/plugins to a local folder and added the following line:
grails.plugin.location.'cached-resources' = "../grailsplugins/cached-resources-1.1"
The intention was to fix this bug myself.
However, strangely enough, when the plugin is locally used the problem with injecting the cacheHeadersService is gone!
How can the plugin act differently when used locally versus when installed normally?
Perhaps it is a loader issue where now the cache-resources-plugin is loaded after whatever is declaring the service, but nonetheless worth reporting.
In the dependencies.groovy in the cache-resources plugin it declares the dependency:
compile ":cache-headers:1.0.4"
but obviosuly it is not loaded before the plugin unless loaded from local directory, strange!
I am also wondering, since the cache-resources plugin declares a dependency on tomcat :
build(":tomcat:$grailsVersion",
":release:2.0.3",
":rest-client-builder:1.0.2") {
export = false
}
is tomcat a requirement? Trying to change to Jetty in the main application the build process fails, saying that tomcat can not be found in the repository.
build ":jetty:2.0.3"// ":tomcat:7.0.52.1"
I just found these similar questions as well:
Cached-resources plugin is not working?
Grails Cache resources not working
Resource not found on grails appliction with cache plugins

UNRESOLVED DEPENDENCIES for commons-codec

I'm trying to retrieve the library for Google Reporting API:
compile 'com.google.apis:google-api-services-analytics:v3-rev74-1.17.0-rc'
but I got an unresolved dependencies error and I don't know what to do with it:
:: commons-codec#commons-codec;1.6: configuration not found in commons-codec#commons-codec;1.6: 'master'. It was required from org.apache.httpcomponents#httpclient;4.0.1 compile
I checked the .grails\ivy-cache\ folder and there's a commons-codec folder with jars of commons-codec-1.5, few xml files ivy-1.5.xml and ivy-1.6.xml and ivydata-1.5.properties and ivydata-1.6.properties. I also tried to delete the whole ivy-cache folder, but the result is the same.
In my grails project i solved it by deleting the folder "commons-codec" from the ivy-cache. The dependency was new loaded then and the error was solved.
Just right after writing my question, I found an answer. Changing the "compile" scope to "build" should resolve the error:
build 'com.google.apis:google-api-services-analytics:v3-rev74-1.17.0-rc'
Actually this solved my previous problem, but raised another one :) A "build" scope includes the library only when compiling, but not at runtime! So I didn't have google-api-services-analytics available when deployed to Tomcat. My final and working solution is:
dependencies {
def googleLibVersion = "1.17.0-rc"
compile("com.google.apis:google-api-services-analytics:v3-rev74-${googleLibVersion}") {
excludes "commons-codec"
}
compile("com.google.http-client:google-http-client-jackson2:${googleLibVersion}") {
excludes "commons-codec"
}
}
Removing .ivy2/cache/ helped me resolving the dependencies.

Grails 2.1.1 - Logback integration

I'm developing with Grails 2.1.1 and now I want to integrate Logback (http://logback.qos.ch) as the default logging framework as it should provide some better logging features and could be also configured via Groovy.
As Logback 1.0.7 (latest) does only work with slf4j 1.6.6 I want to upgrade the Grails dependeny. Grails 2.1.1 is using slf4j 1.6.2. How to do this properly?
I tried the following: in BuildConfig.groovy I exclude grails-plugin-log4j and slf4j-api
grails.project.dependency.resolution = {
// inherit Grails' default dependencies
inherits("global") {
excludes "grails-plugin-log4j", "slf4j-api"
}
...
}
and I try to load slf4j-api 1.6.6 in compile build and runtime along with the other necessary libraries
grails.project.dependency.resolution = {
...
dependencies {
// specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.
compile "org.slf4j:slf4j-api:1.6.6"
build "org.slf4j:slf4j-api:1.6.6",
"ch.qos.logback:logback-core:1.0.7",
"ch.qos.logback:logback-classic:1.0.7"
runtime "org.slf4j:slf4j-api:1.6.6",
"org.slf4j:log4j-over-slf4j:1.6.6", // logback dependency for classic module, as seen on http://logback.qos.ch/dependencies.html
"ch.qos.logback:logback-core:1.0.7",
"ch.qos.logback:logback-classic:1.0.7"
}
...
}
now, if I want to do anything from the Grails commandline, either grails compile or grails clean, it's complaining that it couldn't execute the script because it couldn't find the LoggerFactory class:
| Loading Grails 2.1.1
| Configuring classpath
| Error Error executing script Compile: org/slf4j/LoggerFactory (NOTE: Stack trace has been filtered. Use --verbose to see entire trace.)
java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:156)
at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:132)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:272)
at org.springframework.core.io.support.PathMatchingResourcePatternResolver.<clinit>(PathMatchingResourcePatternResolver.java:169)
| Error Error executing script Compile: org/slf4j/LoggerFactory
How can I upgrade the underlying slf4j-api properly?
If I don't exclude the slf4j-api first, I get a conflict with the "old" 1.6.2 api marked as evicted when calling grails dependency-report...
Also, I'd love to have an external config file for Logback. How would I implement it? With Log4j I just declared a log4jConfigurer bean within the conf/spring/resources.groovy file - how would it be done with Logback?
Has anybody experience in logging Grails 2.1.1 with Logback and could give me any advice for this issue?
As I think that this question would be also a matter of fact for other developers willing to implement the Logback Logging Framework with Grails, I'll share my progress on the topic within this answer - trying not to overload the initial question with progress information.
I still had no luck in updating slf4j within Grails, so I stuck
with the solution to simply overload the slf4j-api dependency.
Grails would show no error on grails dependency-report, just an
"eviction notice" on the older slf4j dependency (1.6.2). This seems
to work but I'll keep on searching for a better solution on this
topic.
I'm now able to load an external config file for Logback through
a ServletContextListener and a ConfigLoader class
implemented in grails-app/src/java, with the
ServletContextListener registered within the web.xml file. (to
get the web.xml simply execute grails install-templates on the
commandline. You'll find it under
grails-app/src/templates/war/web.xml) Be sure to make it the first
<listener/> entry within your web.xml so that Logback gets
configured and loaded as soon as possible.
I found this solution along with the full code sample over at
https://bowerstudios.com/node/896 which was the best and shortest
example I found on this topic which seems to work!
This solution just loaded the external configuration file and used
it within the ConfigLoader class but didn't set it for the whole
Grails application. So I googled around a bit more and I found a
solution from Logback, available at GitHub (https://github.com/qos-ch/logback-extensions) and integrating with the
Spring Framework, so I took these classes from this page and
the LogbackConfigurer class from here and tweaked them to fit
my needs.
Now everything works like a charm and I'am able to create an external configuration file and - what I like best - it's hooking in
with the log object which is injected to e.g. Controller classes
by default.
Hope this is also a help for other developers too ;)
If you've got a better or more "groovy" solution for this, pleas let me know!

Issue Deploying a Grails 2.1.1 app to JBoss because of Xerces

I have a Grails app that uses the Rest plugin
When I drop my war into my JBoss deploy directory and start it up, the deployment of the app fails because of the following error:
2012-11-01 15:48:33,931 ERROR [org.jboss.web.tomcat.service.deployers.JBossContextConfig] XML error parsing: context.xml
org.jboss.xb.binding.JBossXBRuntimeException: Failed to create a new SAX parser
I believe this refers to the grails app containing a version on xercesImpl as well as JBoss having it's own. We usually rectify this by removing xercesImpl from our apps or setting them to "provided" scope.
I'm trying to figure out how I fix this deploy issue. I'm assuming I have to edit the BuildConfig.groovy script and tell it, somehow, to exclude xerces right? How would I do that for this plugin? If this were a "dependency" that appears to be easy to specify the exclusions. But I'm not sure how to do it for this plugin...
any ideas?
In your BuildConfig.groovy add this:
inherits('global') {
excludes 'serializer'
}
It turns out, doing the following in the plugin section of my BuildConfig.groovy did the trick after all...
compile(":rest:0.7"){
excludes "xercesImpl"
}

Resources