Chcecie poznać Ruby on Rails? 29-30.09 w Warszawie odbędą się warsztaty, na których będziecie mieli taką okazję http://railsgirls.com/warsaw. Zgłoszenia przyjmowane są do 21.09. TouK jest jednym ze sponsorów.
How to create a native Java App
Summer internship all new low ceremony code review application
You May Also Like
Private fields and methods are not private in groovy
- byTomasz Kalkosiński
- July 12, 2012
I used to code in Java before I met groovy. Like most of you, groovy attracted me with many enhancements. This was to my surprise to discover that method visibility in groovy is handled different than Java!
Consider this example:
class Person {
private String name
public String surname
private Person() {}
private String signature() { "${name?.substring(0, 1)}. $surname" }
public String toString() { "I am $name $surname" }
} How is this class interpreted with Java?
- Person has private constructor that cannot be accessed
- Field "name" is private and cannot be accessed
- Method signature() is private and cannot be accessed
Let's see how groovy interpretes Person:
public static void main(String[] args) {
def person = new Person() // constructor is private - compilation error in Java
println(person.toString())
person.@name = 'Mike' // access name field directly - compilation error in Java
println(person.toString())
person.name = 'John' // there is a setter generated by groovy
println(person.toString())
person.@surname = 'Foo' // access surname field directly
println(person.toString())
person.surname = 'Bar' // access auto-generated setter
println(person.toString())
println(person.signature()) // call private method - compilation error in Java
} I was really astonished by its output:
I am null null
I am Mike null
I am John null
I am John Foo
I am John Bar
J. Bar As you can see, groovy does not follow visibility directives at all! It treats them as non-existing. Code compiles and executes fine. It's contrary to Java. In Java this code has several errors, pointed out in comments.
I've searched a bit on this topic and it seems that this behaviour is known since version 1.1 and there is a bug report on that: http://jira.codehaus.org/browse/GROOVY-1875. It is not resolved even with groovy 2 release. As Tim Yates mentioned in this Stackoverflow question: "It's not clear if it is a bug or by design". Groovy treats visibility keywords as a hint for a programmer.
I need to keep that lesson in mind next time I want to make some field or method private!
Unable to instantiate default tuplizer
- byRafał Nowak
- August 9, 2013
Log4j and MDC in Grails
- byRafał Nowak
- November 5, 2013
My post is based on post http://burtbeckwith.com/blog/?p=521 from Burt Beckwith's excellent blog, it's definitely worth checking if you are interested in Grails.
Short background story...
How to do that with Grails?
grails create-filters info.rnowak.App.Basket
Initially filter class looks a little bit empty:
class BasketFilters {
def filters = {
all(controller:'*', action:'*') {
before = {
}
after = { Map model ->
}
afterView = { Exception e ->
}
}
}
}
All we need to do is fill empty closures, modify filter properties and put some data into MDC.all is the general name of our filter, as class BasketFilters (plural!) can contain many various filters. You can name it whatever you want, for this post let assume it will be named basketFilter.
Another thing is change of filter parameters. According to official documentation (link) we can customize our filter in many ways. You can specify controller to be filtered, its actions, filtered urls and so on. In our example you can stay with default option where filter is applied to every action of every controller. If you are interested in filtering only some urls, use uri parameter with expression describing desired urls to be filtered.
Three closures that are already defined in template have their function and they are started in these conditions:
- before - as name says, it is executed before filtered action takes place
- after - similarly, it is called after the action
- afterView - called after rendering of the actions view
Putting something into MDC in filter
What we want to do is quite easy: we want to retrieve basket number from parameters and put it into MDC in our filter:
class BasketFilters {
def filters = {
basketFilter(controller:'*', action:'*') {
before = {
MDC.put("basketNumber", params.basketNumber ?: "")
}
after = { Map model ->
MDC.remove("basketNumber")
}
}
}
}
So we are putting something into MDC. But how make use of it in logs?
We can refer to custom data in MDC in conversion patter using syntax: %X{key}, where key is our key we used in filter to put data, like:
def conversionPattern = "%d{yyyy-MM-dd HH:mm:ss} %-5p %t [%c{1}] %X{basketNumber} - %m%n"
And that's it :) We've put custom data in log4j MDC and successfully used it in logs to display interesting values.