Showing posts with label bug. Show all posts
Showing posts with label bug. Show all posts

Friday, October 31, 2014

Grails requires restart after changes in domain class

Grails officially supports domain class reloading since version 2, but recently I found problems using it together with MongoDB GORM plugin, because it required application restart after every change to domain class.
So if Hibernate is primary GORM and Mongo is used only for some particular cases, disabling it can be a good option to make development easier.

Friday, May 9, 2014

Chaining jQuery promises in for cycle

JQuery has nice support for promises, but some stuff is not obvious and recently I just stuck with one particular problem: I had to prepare a bunch of closures in for cycle and added them to deferred object which was resolved afterwards. All of them had to be executed strictly one after another, but there are ajax calls so I cann't do it old fashioned way, since sinchronous ajax is weird.
So I did this:

function doPromise(someVar) {
  return function() {
    return $.ajax({ type: 'POST', url: 'http://myurl', success: doStuff, error: panic});
  }
};
function start() {
  var promise = $.Deferred();
  for (var i=0;i<10;i++) {
    promise.then(doPromise(i) );
  }
  promise.resolve();
};


And I was expecting it being called one after another, which was not the case and all of them fired simultaniously. As I found out finally, all thens are equal and I had to add them, not to original promise, but dirrectly to each other, which is a little confusing to me, but works. So this is the correct code for my case:

function start() {
  var original = $.Deferred();
  var promise = original;
  for (var i=0;i<10;i++) {
    promise = promise.then(doPromise(i) );
  }
  original.resolve();
};


Tuesday, April 15, 2014

IllegalStateException Method on class was used outside of a Grails application

After upgrade to 2.3 and running Geb functional UI tests, they started to fail with error:

java.lang.IllegalStateException: Method on class [my.Test] was used outside of a Grails application. If running in the context of a test using the mocking API or bootstrap Grails correctly.
       at my.Test.currentGormStaticApi(Test.groovy)
       at my.Test.$static_methodMissing(Test.groovy)
       at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
       at groovy.lang.MetaClassImpl.invokeStaticMissingMethod(MetaClassImpl.java:1372)
       at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1360)
       at groovy.lang.ExpandoMetaClass.invokeStaticMethod(ExpandoMetaClass.java:1123)
       at org.codehaus.groovy.runtime.callsite.StaticMetaClassSite.call(StaticMetaClassSite.java:50)
       at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
       at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
       at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)


After some pretty painful investigation, I found out that problem is when running tests with new fork mode properties, and is easy to solve by removing these options from BuildConfig.groovy:

grails.project.fork = [
    test: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, daemon:true],
    run: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, forkReserve:false],
    war: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, forkReserve:false],
    console: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256]
]

Wednesday, April 24, 2013

ChannelResolutionException in Spring Integration with Groovy

Recently, after launching Spring Integration beans I got weird exception:
ChannelResolutionException: no output-channel or replyChannel header available
After some googling I found out that this error means that Spring Integration tries to configure reply channel, which in my case meant that I am replying into channel-adapter, which is not possible. So basically, problem was that my service method was defined as:
def myServiceMethod()

which Spring understands as it returns something, even if it does not. So this should be told explicitly, like:
void myServiceMethod()

and this is it.

Wednesday, April 17, 2013

jQuery / Javascript method runs several times after single call

Recently, I was developing web page and attached click handler to button, which was loading some content into div element. What was unexpected, after first click - it loaded everything just fine, but each next click was increasing amount of method calls.
As I found out, problem was that after successful method execution it also loaded default page template with every new fragment, including JavaScript page initialization scripts, which was adding new handlers to all old buttons, and so on, and so on.
It was easy to fix by creating new empty template specifically for HTML fragments.
I had this problem with Grails, but any template engine with too many conventions and defaults can be vulnerable.

Friday, January 25, 2013

grails-coffeescript-resources is not working after deploying war in production

There is great Grails plugin that allows to work with CoffeeScript very easily, compiles .coffee files on the fly and does all dirty work.
However, once I tried to deploy my application to test environment, all CoffeeScript files became available in browser as is, without compilation. After some investigation I found out that problem is that it does not supports applications deployed as packed WAR files (with unpackWARs="false" in server.xml), it was pretty easy to fix by modifying plugin script grails-app/resourceMappers/CoffeeScriptResourceMapper.groovy by changing:
 
      File input = grailsApplication.parentContext.getResource(resource.sourceUrl).file

to this

      File input
      try {
        input = grailsApplication.parentContext.getResource(resource.sourceUrl).file
      } catch (FileNotFoundException e) {
        input = new File(original.absolutePath)
      }


and it should work.
One problem is that this change is inside plugin, so you can't do change in your code, and should change plugin itself. I submitted fix with pull request on GitHub, hopefully it will be merged. Until then it is possible to compile your own version from here, or just replace this one line on build server.


Friday, January 18, 2013

Working around grails.serverURL redirect in Grails 2

The most annoying issue with Grails 2 migration is that it requires redirection to grails.serverURL when it is specified. This property is needed if there are absolute links in application (in emails, for example).
First problem that I had with it, was after deploying application to test environment. We deploy production version, so all redirects became redirects to production, this could be solved by externalizing Grails configuration.
Second problem was more severe. We have following setup: load balancer with two nodes behind it. Our deployment script takes first node down, deploys, runs smoke tests, releases first node, takes second node down, deploys, smoke tests, releases.
So basically, production URL is load balancer's entry point, and when smoke tests run on node which is down it is never redirected to tested server (because it is down and it is behind load balancer), so every redirect (after spring security login, for example), breaks tests flow.
After some digging around, I found the best option is to abandon grails.serverURL - which is totally unusable now, and add to email link generation my own parameter from externalized Grails configuration (for each environment). This is sad as createLink with absolute parameter was great function and it didn't required dragging custom parameters.
That is how it is now.
What I would love to see in the future is grails.serverURL is used ONLY in all links generated with absolute:true and nowhere else, but all redirects work as if grails.serverURL not specified at all.

Thursday, January 17, 2013

"Cannot find any VM in Java Home ..." error in Tomcat

During migration from JDK 6 to 7, I found strange issue: Tomcat was working fine when starting via catalina.sh, but was failing when starting via jsvc with just this error:

Cannot find any VM in Java Home /usr/lib/jvm/jdk1.7.0_10/

Jsvc recompilation or any other measure was not helping, but finally I found out that it was running flawless with specific x64 version of JDK instead of i586 version.

Fixing GORM UserType after migration to version 2

Grails allows to define custom UserType to properties like in regular Hibernate, by specifying them next to properties in domain objects, like:


  someproperty type: MyUserType

But after migrating to Grails 2.2, these stopped working and Grails started to treat them as plain objects (enumerations in my particular case). Fortunately, this was easy to fix by defining all custom user types in Config.groovy, like:


grails.gorm.default.mapping = {
  'myproperty-type'(type: my.org.MyUserType, class: my.org.MyEnum)
}

This also defines mapping for all properties of specific type, so no need to do it in every domain class.

Wednesday, October 24, 2012

NullPointerException when saving Grails object

Recently I got very strange NPE while saving updated entity in Grails application:

java.lang.NullPointerException
 at com.test.MyController$_closure5.doCall(MyController.groovy:69)
 at com.test.MyController$_closure5.doCall(MyController.groovy)
 at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:149)
 at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:259)
 at $Proxy49.forward(Unknown Source)
 at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:206)
 at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:179)
 at java.lang.Thread.run(Thread.java:662)

All I was doing on line 69 was just calling save() method, object obviously was not null, all fields and dependencies too. Even more - saving another object from same method was perfectly fine, but not one particular.
Finally, I got the reason - object had null in it's version field. Obviously migration was not done properly or it was manually created object in bad schema, but setting version solved my problem easily, but bad error reporting - didn't helped.

Monday, April 2, 2012

Redis exception: Cannot use Jedis when in Multi.

Jedis newbie problem when adding transactions to Redis client application:


Cannot use Jedis when in Multi. Please use JedisTransaction instead.
redis.clients.jedis.exceptions.JedisDataException: Cannot use Jedis when in Multi. Please use JedisTransaction instead.
 at redis.clients.jedis.BinaryJedis.checkIsInMulti(BinaryJedis.java:1651)
 at redis.clients.jedis.Jedis.hmset(Jedis.java:724)
 at test.TestService.updateSomething(TestService.groovy:39)
 at test.TestService$_processBet_closure1.doCall(TestService.groovy:16)
 at grails.plugin.redis.RedisService.withRedis(RedisService.groovy:67)

Description of exception is absolutely correct though a little confusing. Problem is that you are trying to call methods on Redis connection object instead of Transaction object. So most probably you have something like:


  Jedis jedis = pool.getResource()
  jedis.watch('foo')
  ...
  def transaction = jedis.multi()
  jedis.set("foo", value.toString())
  def result = transaction.exec()


But instead, you should have something like:


  Jedis jedis = pool.getResource()
  jedis.watch('foo')
  ...
  def transaction = jedis.multi()
  transaction.set("foo", value.toString())
  def result = transaction.exec()


Thursday, February 16, 2012

sprintf, printf bug in Groovy

Recently I found strange issue when running Grails application on Linux. Sometimes, when formatting decimal number with sprintf it does not work and simply returned original number. After some investigation I found that this is general Groovy behavior and simple script with:

println sprintf('%.2f', 1/609)

returns 0.0016420361 as result, when it suppose to return just 0.00. I was not able to reproduce this bug on Windows or in plain Java, so most probably this is GDK issue, but I didn't investigated it very carefully.
Anyway, this is very easy to fix by casting numbers into decimals explicitly, so this code:

println sprintf('%.2f', 1d/609)

returns nice and correct results.

Friday, October 14, 2011

InvalidClassException: GrailsUser and plugin upgrade

Recently when I tried to deploy new version of application on live server without downtime, I got error:

2011-10-14 11:02:52,058 [Tribes-Task-Receiver-4] ERROR org.apache.catalina.ha.session.DeltaManager- Manager [localhost#]: Unable to receive message through TCP channel
java.io.InvalidClassException: org.codehaus.groovy.grails.plugins.springsecurity.GrailsUser; local class incompatible: stream classdesc serialVersionUID = -3114204362518930756, local class serialVersionUID =
        at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:579)
        at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1600)
        at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1513)
        at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1600)
        at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1513)
        at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1749)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346)
        at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1963)
        at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1887)
        at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1770)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346)
        at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1963)

Basically, error is trivial, just some Spring security classes are not versioned and cluster can't synchronize users data. Fortunately, as I have found out, no hacking is needed and it can be easily fixed by upgrading spring-security-core plugin to the latest version.

To upgrade to latest version, just uninstall plugin and install it again, like:

grails uninstall-plugin spring-security-core
grails install-plugin spring-security-core