Retrofit is one of the most popular REST client for Android, if you never use it, it is high time to start. There are a lot of articles and tutorial talking about Retrofit. I just would like to show how to mock a REST server during develop of app and in unit test when you are using Dagger as DI.
Read More...
wtorek, 25 lutego 2014
wtorek, 15 października 2013
Roboguice lecture
26th September I conducted my first lecture in front of Warsaw society of Mobile developers. I had only 1 hour, thus In very concise way, I showed every curious features of Roboguice. From the simplest bindings, observes mechanism etc. to Inject customActivity using provides method and NullProvider. Unfortunately there isn't any video of the event, so at least I publish a slide show.
Read More...
Roboguice from Paweł Byszewski
piątek, 26 lipca 2013
Grails coffeescript plugin
Brian Kotek has written great plugin to integrate CoffeeScript into Grails project - grails-coffeescript-compiler-plugin. Everything about configuration of the plugin you can find on wiki. The plugin cooperates with two coffeescript compilers Rhino and Node. Accordingly to default behaviour ,when both compilers are installed on system, the Node will be chosen. Unfortunately there are some tiny differences between Rhino and Node. In my case I was the only person in the team that has installed Rhino and Node (others have only Rhino). Our code work properly only with cooperation with Rhino.
Because Brian Kotek develop almost everything to force using Rhino I have forked and add few lines of code to make forcing Rhino available through plugin configuration in Config.groovy:
Read More...
Because Brian Kotek develop almost everything to force using Rhino I have forked and add few lines of code to make forcing Rhino available through plugin configuration in Config.groovy:
'coffeescript-compiler' {
pluginConfig {
forceRhino = true
minifyInEnvironment = [ Environment.PRODUCTION ]
}
appSource {
coffeeSourcePath = 'src/coffee'
jsOutputPath = 'web-app/js/compiled'
}
}
Kotek already has accepted my pull request so you can use original plugin instead of my fork.
czwartek, 25 lipca 2013
Grails one to many: Find object by property of one of child-object from collection
Have you ever looking for solution of a problem that became obvious in the moment that you find it. In my case I have tried to find Grails domain object by property of one of its child Assume that there are persons and pets. Each person can have one or more pets. Each pet has one owner.
Lets find all persons that have at least one pet with name "reksio". This is really simple challenge. That how it looks with using namedQueries
This is really simple, clear and obvious.
Read More...
class Person {
String name
static hasMany = [pets: Pet]
}
class Pet {
String name
int age
static belongsTo = [person: Person]
}
Lets find all persons that have at least one pet with name "reksio". This is really simple challenge. That how it looks with using namedQueries
class Person {
String name
static hasMany = [pets: Pet]
static namedQueries = {
findByPetName { String petName ->
pets {
eq "name", petName
}
}
}
}
Thus it is time to check if the solution really works. I have prepared some integration test using Spock.
class PersonIntegrationSpec extends IntegrationSpec {
def 'find all persons with pet with given name'() {
given:
Pet reksio1 = new Pet(name: "reksio", age: 2)
Pet rocky1 = new Pet(name: "rocky", age: 4)
Pet max = new Pet(name: "max", age: 7)
Person person1 = new Person(name: "Jack")
[reksio1, rocky1, max].each { person1.addToPets(it) }
person1.save(failOnError: true)
Pet teddy = new Pet(name: "teddy", age: 2)
Pet reksio2 = new Pet(name: "reksio", age: 12)
Pet gizmo = new Pet(name: "gizmo", age: 11)
Person person2 = new Person(name: "Kate")
[teddy, reksio2, gizmo].each { person2.addToPets(it) }
person2.save(failOnError: true)
Pet rocky2 = new Pet(name: "rocky", age: 2)
Pet bandit = new Pet(name: "bandit", age: 12)
Person person3 = new Person(name: "John")
[rocky2, bandit].each { person3.addToPets(it) }
person3.save(failOnError: true)
when:
List persons = Person.findByPetName("reksio").list()
then:
persons.size() == 2
persons.contains(person1)
persons.contains(person2)
}
}
This is really simple, clear and obvious.
środa, 29 maja 2013
Phonegap / Cordova and cross domain ssl request problem on android.
In one app I have participated, there was a use case:
You have to remember that secure connection to service with self-signed certificate is risky and unrecommended. But if you know what you are doing there is some workaround of the security problem. Behavior of method
Thus add new class extended CordovaWebViewClient and override ‘onReceivedSslError’. I strongly suggest to implement custom onReceiveSslError as secure as possible. I know that the problem occours when app try connect to example.domain.com and in spite of self signed certificate the domain is trusted, so only for that case the SslError is ignored.
Now the app created in release mode can connect via https to services with self-signed SSl certificates.
Read More...
- User fill up a form.
- User submit the form.
- System send data via https to server and show a response.
- ant release
- align
- signing
res/xml/cordova.xml
If whitelist looks fine, the error is most likely caused by inner implementation of Android System. The Android WebView does not allow by default self-signed SSL certs. When app is debug-signed the SSL error is ignored, but if app is release-signed connection to untrusted services is blocked.
Workaround
CordovaWebViewClient.onReceivedSslError
must be changed.Thus add new class extended CordovaWebViewClient and override ‘onReceivedSslError’. I strongly suggest to implement custom onReceiveSslError as secure as possible. I know that the problem occours when app try connect to example.domain.com and in spite of self signed certificate the domain is trusted, so only for that case the SslError is ignored.
public class MyWebViewClient extends CordovaWebViewClient {
private static final String TAG = MyWebViewClient.class.getName();
private static final String AVAILABLE_SLL_CN
= "example.domain.com";
public MyWebViewClient(DroidGap ctx) {
super(ctx);
}
@Override
public void onReceivedSslError(WebView view,
SslErrorHandler handler,
android.net.http.SslError error) {
String errorSourceCName = error.getCertificate().
getIssuedTo().getCName();
if( AVAILABLE_SLL_CN.equals(errorSourceCName) ) {
Log.i(TAG, "Detect ssl connection error: " +
error.toString() +
„ so the error is ignored”);
handler.proceed();
return;
}
super.onReceivedSslError(view, handler, error);
}
}
Next step is forcing yours app to use custom implementation of WebViewClient.
public class Start extends DroidGap
{
private static final String TAG = Start.class.getName();
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
super.setIntegerProperty("splashscreen", R.drawable.splash);
super.init();
MyWebViewClient myWebViewClient = new MyWebViewClient(this);
myWebViewClient.setWebView(this.appView);
this.appView.setWebViewClient(myWebViewClient);
// yours code
}
}
That is all ypu have to do if minSdk of yours app is greater or equals 8.
In older version of Android there is no class
android.net.http.SslError
So in class MyCordovaWebViewClient class there are errors because compliator doesn’t see SslError class. Fortunately Android is(was) open source, so it is easy to find source of the class. There is no inpediments to ‘upgrade’ app and just add the file to project. I suggest to keep original packages. Thus after all operations the source tree looks like:Class SslError placed in source tree. |
sobota, 27 kwietnia 2013
Migration project to grails 2.2
Once upon a time in my team appeared a thoughts : ”Lets migrate from grails 2.1 to 2.2”. Hmm, why not. This operation is not simple change of framework version. It is more like a chain reaction, because new grails requires groovy 2.0 and groovy 2.0 require Spock 0.7. Thus in our case the migration resulted in upgrading three basic cores of the application.
So lets see what new features we gain thanks to the migration.
set system variables
Then, in project settings update versions of required libraries
Now you ready to check how far from the end of the journey you are. So go to the project dir and fire:
At the first glance situation looks awful. Source of tests and tested Classes did not change and just do not work with spock 0.7. Unfortunately there is no way to migration to Grails 2.2 and still use spock 0.6. Fortunately there is no need to rebuild the whole structure of your app in order to remove mocks of the same Class. Maybe the resolution is not nice and good looking but at least works. In spock 0.7 there are few new mock objects, and one of them is GroovyMock. It make mock object to be more groovylike – with whole automagic stuff underneath. In most of cases there is no reasonable reasons to use GroovyMock instead of Mock but it will fix your tests. Thus, all you have to do is in one test use Mock and in the other GroovyMock. Thus in every place where is a problem use Mock in unit tests and GroovyMock in integration tests.
I have been still waiting for blink a stun and it appeared when I’ve was seeing checked VM arguments of grails 2.2 tests process. At the first sight those values seemed to be to poor.
I have compared it with arguments for grails 2.1 values of almost each important parameter was significant higher for grails 2.1. I have never given those parameters explicitly, so it seemed like in case of grails 2.2 there are changed 'default' values of JVM argument. Fortunately user can provide custom JVM arguments. Thus, in order to bring back fast test process, for example type:
Read More...
So lets see what new features we gain thanks to the migration.
Grails 2.2.0
The Grails team, on official website described all changes. The most important are:- tuning of the developer server,
- improved support for namespace conflicts between various plugins occurring in url mapping,
- access to Hibernate's SQL projection API in criteria queries.
Groovy 2.0
By googling, you can find a lot of articles about 2.0 version, whereas this post is about how to migrate your grails project. Thus I think in this case, it is sufficient to quote the Groovy website::“In a nutshell, Groovy 2.0 add static type checking to let the compiler tell you about the correctness of your code, static compilation for the performance of the critical parts of your application, modularity by splitting the Groovy JAR into smaller feature-oriented modules as well as allowing you to create your own extension modules, JDK 7 Project Coinsyntax enhancements so that Groovy marries itself well with Java, and JDK 7 Invoke Dynamic integration to benefit from the dynamic language support of the JVM.”
Spock 0.7
Spock 0.7 is the first version compatible with groovy 2.0, thus if you still used earlier version, now you will have to upgrade yours test framework. At the first glimpse it could be actually a good idea because Spock0.7 has a lot of quite useful features. Firstly there are some usability improvements e.g.:- improved mocking failure message for to ToManyInvocationsError and ToFewInvoactionError
- grouping condition with same target object,
- grouping interactions with same target object,
- improved Failure Messages for notThrown and noExceptionThrown.
- new mocking objects: Stubs, Spies, Groovy Mock, Global Mocks,
- pooling conditions for testing asynchronous code,
- @Beta annotation.
Let's get migrate
First steps are rather standard and shouldn't be supprising. You have to prepare the environmentset system variables
- GRAILS_HOME=path_to_grails_2.2
- PATH=PATH:GRAILS_HOME/bin
Then, in project settings update versions of required libraries
- grails 2.2
- groovy 2.0
- spock 0.7
Now you ready to check how far from the end of the journey you are. So go to the project dir and fire:
grails clean
grails upgrade
grails test-app
If there is no erros - congratulations You have just migrate to Grails 2.2. But if any errors occured,
further steps and problem, strongly depends on the code of yours project and state of the grails cache.
So at the first I suggest to clear grails cache. Just run
rm -rf ~/.grails
and then you can firegrails test-app
and now you can go for a lunch or a long coffee break because grails will recreate .grails – that means in most of cases, download a lot of stuff from the Internet.
Works only when separately and CannotCreateMockException()
In my case, first test-app failed. There were a lot of errors connected with CannotCreateMockException() After some investigation, occurred that- grails test-app unit: - works fine
- grails test-app integration: - works fine
- grails test-app - FAIL
class FooSpec {
Foo foo = Mock(Foo)
…....
}
class FooIntegrationSpec {
Foo foo = Mock(Foo)
…...
}
then
- grails test-app FooSpec => Pass
- grails test-app FooIntegrationSpec => Pass
- grails test-app FooSpec FooIntegrationSpec => Fail
At the first glance situation looks awful. Source of tests and tested Classes did not change and just do not work with spock 0.7. Unfortunately there is no way to migration to Grails 2.2 and still use spock 0.6. Fortunately there is no need to rebuild the whole structure of your app in order to remove mocks of the same Class. Maybe the resolution is not nice and good looking but at least works. In spock 0.7 there are few new mock objects, and one of them is GroovyMock. It make mock object to be more groovylike – with whole automagic stuff underneath. In most of cases there is no reasonable reasons to use GroovyMock instead of Mock but it will fix your tests. Thus, all you have to do is in one test use Mock and in the other GroovyMock. Thus in every place where is a problem use Mock in unit tests and GroovyMock in integration tests.
class FooSpec {
Foo foo = Mock(Foo)
…....
}
class FooIntegrationSpec {
Foo foo = GroovyMock(Foo)
…...
}
and now
grails test-app FooSpec FooIntegrationSpec => Pass
Spock 0.7 is so slow?
Thus, when all tests are passed there is last problem to defeat. After migration tests work amazingly slow. Before migration grails test-app took~7min, and after it takes even ~30min. I’ve noticed that the difference grows up exponentially with tests quantity. At the first I thought about some memory issue, so I decided to monitored parameters of the tests process. Comparison of charts of Heap Memory usage and CPU usage did not bring any explanation.Charts for 'grails test-app" process - all tests and Grails 2.1 |
Charts for 'grails test-app" process - almost half tests and Grails 2.2.0 |
export GRAILS_OPTS="-Xmx2048M -Xms768M -XX:PermSize=256m -XX:MaxPermSize=256m"
grails test-app
This way I can manage time of my tests, so if only I have some free hardware resources, I provide specific JVM arguments and my tests may shorten and make take even under 2 minutes.