Andre's Blog

20160723 Sometimes A Sprint Fails

[AGILE]

This week my plan was to combine the code examples for CISystem to one working example :

  1. read the network configuration from a json config file
  2. determine the local IP address
  3. start some nodes on the same machine with their server sockets on different ports
  4. tell every node only how to reach 2 other the other nodes and let them find out the others by communicating over the network with the other nodes

If you work in a SCRUM team, this may be no new news to you : Sometimes a sprint fails.

This does not mean you did not give enough to reach the goal and it does not mean you did not achieve a lot of it but it is just not finished.

One reason for failed sprints can be you did not see the whole effort and have planned too much for it.

This happened to me this week. My plan was to adapt existing code to fit together, which was no problem. To make it more demanding I wanted to have independent Java programs communicate via sockets to exchange the network configuration of the other nodes. I think I would have managed this, I have already found out how to set up synchronized lists and maps to handle the information at a node which is asking and responding on different threads with other nodes at the same time.

What happened to me was, I totally underestimated the fact, that I have no experience with building software with Gradle with dependencies to other jar files. I have my Gradle script for building my own .jar files and it was easy to find out how to implement the dependency to the groovy-all-2.4.7.jar file, which I have only referenced in a classpath in the shell when calling javac and java till now.

It compiles really nice with :

apply plugin: 'java'

repositories {

    mavenCentral()

}

jar {

    dependencies {
      compile 'org.codehaus.groovy:groovy-all:2.4.7'
    }

    manifest {
        attributes 'Main-Class': 'com.wartbar.cisystem.CISystem'
    }

}

What I did not achieve yet is to make it run.

java -cp .:c:\tools\groovy-2.4.7\embeddable\groovy-all-2.4.7.jar -jar build\libs\NetworkInitialization.jar

Exception in thread "main" java.lang.NoClassDefFoundError: groovy/lang/GroovyClassLoader
        at com.wartbar.data.ReadConfigNetwork.read(ReadConfigNetwork.java:11)
        at com.wartbar.cisystem.CISystem.readConfigNetwork(CISystem.java:31)
        at com.wartbar.cisystem.CISystem.main(CISystem.java:62)
Caused by: java.lang.ClassNotFoundException: groovy.lang.GroovyClassLoader
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 3 more

It means, the class groovy.lang.GroovyClassLoader was available while compilation, but not while execution.

I was already googling for some time on this problem, but till now I only have these ideas :

  1. I can run my code through a Gradle JavaExec task, I guess that would work, but I don't know how this would help me.
  2. I can compile my code as before with -cp, I already know that works, but I want to do it with Gradle.
  3. I can ask some colleagues and friends and go on googling.

This week was no failure for me, it has just shown me I had planned too much and did not split my tasks like should have done it (read my blog post about Elephant Carpaccio Or How Many Things Can I Get Done On Sunday for more details).

Some ways to split my task could be :

  1. Simulate the Groovy/Json part by using hard coded data and just make everything work without adding new functionality.
  2. Make the network communication between the different nodes work.
  3. Make execution based on a Gradle compiled jar file work.

The second task can be split again into :

The third task has an external dependency, it depends on when I find out how to do it. I should better start soon with contacting some friends :)

I just want to say, do not let your sprint totally depend on external dependencies, always have some other story to do while waiting for the missing solution to show up.

My short summary how to ensure you have something to present to your stakeholders at the end of a sprint :

  1. split your stories and split your tasks
  2. reduce external dependencies

Personally I think, the best is to kick external dependencies out of the scope and use some fake instead. You can integrate the real code when it works, but your sprint should not depend on code where you don't know how to write it or where to get it.

Yes, 2 points are enough here, 3 points don't make it better and if you achieve to implement these 2 points in your SCRUM, you have achieved a lot!

If you think this is too simple, you cannot just split stories and tasks and work around external dependencies, maybe this article from Eike could be something you were looking for :

Kikentai Management : List hell: 3 reasons list are evil

Select where to go ...


The Blog
My Technical Blogs
Projects
Blogs Of Friends
RSS
CV/About
Me