Simple caldav4j example in java and clojure

I was trying to access a caldav calendar through java and clojure to build a small application. But it wasn’t too easy.

caldav4j seemed to be very confusing and not so well maintained. There is no quick start guide and you are directed to have a look at the unit tests. But they are a compilation of interconnected classes and their hierarchies including a lot of deprecated classes being used – pretty confusing for a newcomer.

I had also problems using the alternative ical4j and it’s caldav connector. After some debugging it seemed incompatible with zimbra because of some strange filter constraints.

This might all be due to the fact that caldav is a complex protocol and I accepted to dig deeper into caldav4j.

Enough of the yacking, I traced down the necessary wire to build a basic example and hope it’ll help others looking for a quick start.

Java: https://github.com/dedeibel/list-events-caldav4j-example

Clojure: https://github.com/dedeibel/list-events-caldav4j-example-clojure

I tested it with zimbra. For google calendar a little more work might be required. The key might be in the GoogleCalDavDialect.java class.

 
Java:
 

    HttpClient httpClient = new HttpClient();
    // I tried it with zimbra - but I had no luck using google calendar
    httpClient.getHostConfiguration().setHost("CALDAVHOST", 443, "https");
    String username = "username";
    UsernamePasswordCredentials httpCredentials = new UsernamePasswordCredentials(username, "secret");
    httpClient.getState().setCredentials(AuthScope.ANY, httpCredentials);
    httpClient.getParams().setAuthenticationPreemptive(true);
    // Need a proxy?
    //httpClient.getHostConfiguration().setProxy("phost", 8080);

    CalDAVCollection collection = new CalDAVCollection(
        "/dav/"+ username +"/Calendar",
        (HostConfiguration) httpClient.getHostConfiguration().clone(),
        new CalDAV4JMethodFactory(),
        CalDAVConstants.PROC_ID_DEFAULT
        );

    GenerateQuery gq=new GenerateQuery();
    // TODO you might want to adjust the date
    gq.setFilter("VEVENT [20131001T000000Z;20131010T000000Z] : STATUS!=CANCELLED");
    // Get the raw caldav query
    // System.out.println("Query: "+ gq.prettyPrint());
    CalendarQuery calendarQuery = gq.generate();
    List<Calendar>calendars = collection.queryCalendars(httpClient, calendarQuery);

    for (Calendar calendar : calendars) {
      ComponentList componentList = calendar.getComponents().getComponents(Component.VEVENT);
      Iterator<VEvent> eventIterator = componentList.iterator();
      while (eventIterator.hasNext()) {
        VEvent ve = eventIterator.next();
        System.out.println("Event: "+ ve.toString());
        System.out.println("\n\n");
      }
    }

 
Clojure:
 

defn- create-query []
  (let [gq (GenerateQuery.)]
    ; Date Format yyyyMMdd
    (.setFilter gq "VEVENT [20131001T000000Z;20131010T000000Z] : STATUS!=CANCELLED")
    (.generate gq)))

(defn -main []
  (let [http-client (initialize-http-client)
        collection-path (:collection-path configuration)
        host-configuration (.clone (.getHostConfiguration http-client))
        method-factory (CalDAV4JMethodFactory.)
        collection (CalDAVCollection. collection-path host-configuration method-factory CalDAVConstants/PROC_ID_DEFAULT)
        calendars (.queryCalendars collection http-client (create-query))
        ]
    (doseq [cal calendars
            event (-> cal (.getComponents) (.getComponents Component/VEVENT))]
      (println "Event: " event)
      (println "\n\n"))))

Clojure core.logic cheatsheets

I am currently having a look at clojure core.logic and was missing some kind of reference documentation. There are a lot of examples and tutorials but I never had an overview about what’s available.

In a google groups discussion the idea of a reference documentation like clojure cheat sheets came up. https://groups.google.com/forum/#!topic/clojure/ScJa_o4lP2k

So I decided to create one, view it directly: cheatsheet on github

Have a look at the github project: https://github.com/dedeibel/clojure-core-logic-cheatsheets

Thanks to the original author of the cheatsheet generator Michael Fogus and Andy Fingerhut.

Thanks goes to xavriley who created a cool version of clojuredocs for core.logic which is where the cheatsheet entries link to.

How to install oracle java 7 update 11 (jdk-7u11) on debian linux

Currently you can’t install the new java sdk 7 update 11 from oracle using java_package. Usually you can simply follow this instruction: Installing oracle jre / sdk on debian.

Unfortunately the error is: No matching plugin was found.

But you can modify the script /usr/share/java-package/oracle-j2sdk.sh to accept the new package:

15,16c15,16
<       "jdk-7u"[0-9]"-linux-i586.tar.gz") # SUPPORTED
<           j2se_version=1.7.0+update${archive_name:6:1}${revision}
---
>       "jdk-7u"[0-9][0-9]"-linux-i586.tar.gz") # SUPPORTED
>           j2se_version=1.7.0+update${archive_name:6:2}${revision}
31,32c31,32
<       "jdk-7u"[0-9]"-linux-x64.tar.gz") # SUPPORTED
<           j2se_version=1.7.0+update${archive_name:6:1}${revision}
---
>       "jdk-7u"[0-9][0-9]"-linux-x64.tar.gz") # SUPPORTED
>           j2se_version=1.7.0+update${archive_name:6:2}${revision}

Worked for me:

The Debian package has been created in the current directory. You can
install the package as root (e.g. dpkg -i oracle-j2sdk1.7_1.7.0+update11_amd64.deb).

(#:/tmp)- dpkg -i oracle-j2sdk1.7_1.7.0+update11_amd64.deb
(Reading database … 225711 files and directories currently installed.)
Preparing to replace oracle-j2sdk1.7 1.7.0+update7 (using oracle-j2sdk1.7_1.7.0+update11_amd64.deb) …
Unpacking replacement oracle-j2sdk1.7 …
Setting up oracle-j2sdk1.7 (1.7.0+update11) …

(#:/tmp)- java -version
java version „1.7.0_11“
Java(TM) SE Runtime Environment (build 1.7.0_11-b21)
Java HotSpot(TM) 64-Bit Server VM (build 23.6-b04, mixed mode)

There is also a bug report: Bug#698108: jdk7u11 not supported

Edit: also works for java 7 update 12 (jdk-7u12), java 7 update 13 (jdk-7u13), java 7 update 14 (jdk-7u14) and java 7 update 15 (jdk-7u15)

Edit: Oh boy, too many updates recently.

Clojure store persistent data structures gotcha – load-file size limit

In clojure – the data structure and their default representation are suited as readable and portable format to persist data. But there is a small pitfall in using it.

Data Structure example:

{
  :request-time 2636,
  :status 200,
  :headers
  {
    "server" "Server",
    "content-encoding" "gzip",
  }
}

Be aware that this function is intended to load code only. If your data structures or a string in them grow bigger than around 65,535 it crashes.

Exception similar to:

java.lang.ClassFormatError: Unknown constant tag 49 in class file parse$eval13

Please use read-string instead.

Example: (read-string (slurp "data.clj"))

Source: Rich Hickey on google groups Google Groups

GWT 2.2.0 and EXT GWT no success

I tried to use EXT GWT with GWT 2.2.0 and had no success … no one told me I couldn’t do that.

Afterwards I found out there really is no accurate version requirement noted for EXT GWT. „GWT 1.5 or above is required“ from the helpcenter was not very helpful here.

What I started with and wanted to use was:

<gwtVersion>2.2.0</gwtVersion>
<gwtMavenVersion>2.2.0</gwtMavenVersion>
<gwtLogVersion>3.1.0</gwtLogVersion>
<ginVersion>1.5</ginVersion>
<!-- My Wish: From the Sencha Roadmap, not yet released: 3.0 -->
<extGwtVersion>2.2.0</extGwtVersion>

(maven Dependency configuration)

Which resulted in compilation errors:

$ mvn -Dmaven.test.skip package
java.lang.IncompatibleClassChangeError: Found interface com.google.gwt.core.ext.typeinfo.JClassType, but class was expected at com.extjs.gxt.ui.rebind.core. TemplatesGenerator$SourceGenerator.validateType(TemplatesGenerator.java:142) at com.extjs.gxt.ui.rebind.core. TemplatesGenerator$SourceGenerator.generate(TemplatesGenerator.java:97) at com.extjs.gxt.ui.rebind.core. TemplatesGenerator.generate(TemplatesGenerator.java:56)
...

I found some board entries about that. So I had to downgrade GWT and a couple of libraries like the maven gwt plugin, gin and gwt log. Thanks to maven this was less horrible than it could have been.

<gwtVersion>2.1.1</gwtVersion>
<gwtMavenVersion>2.1.0-1</gwtMavenVersion>
<gwtLogVersion>3.0.2</gwtLogVersion>
<ginVersion>1.0</ginVersion>
<extGwtVersion>2.2.0</extGwtVersion>
<warPluginVersion>2.1.1</warPluginVersion>

So, dear vendors, please make more accurate requirement definitions.

Java DDOS 2.2250738585072012e-308 with curl

There seems to be an easy exploit for the problem going around in the news.

curl -H „Accept-Language: en-us;q=2.2250738585072012e-308“ URL

Apparently works on any Tomcat-server calling getLocale() on the request or most spring applications.

Meanwhile there is java patch for the problem, update your boxes!

Release Notes: http://blogs.oracle.com/henrik/2011/02/jdk_6_update_24_released.html
Security Alert: http://www.oracle.com/technetwork/topics/security/alert-cve-2010-4476-305811.html

For my servers it did not have an effect but maybe you had success? Please leave a comment.

Edit:

You should all have received a java security update by now. If not, you could simply use the following code to reproduce the bug locally.

$ cat Runhang.java 
class Runhang {
  public static void main(String[] args) {
    System.out.println("Test:");
    double d = Double.parseDouble("2.2250738585072012e-308");
    System.out.println("Value: " + d);
  }
}

$ javac Runhang.java
$ java Runhang &
... wait and kill it :)

FizzBuzz Aufgabe in Clojure

Es gibt eine Code Kata die nennt sich FizzBuzz http://codingkata.org/katas/unit/fizz-buzz. Ich habe einmal versucht die Aufgabe in Clojure zu realisieren. Die meiste Zeit habe ich damit verbracht, geeignete Funktionen für meine Zwecke zu finden, da dies so ziemlich meine ersten Zeilen in Clojure sind.

(defn fizzbuzz [n] (cond
    (and (zero? (mod n 3)) (zero? (mod n 5))) "fizzbuzz"
    (zero? (mod n 3)) "fizz"
    (zero? (mod n 5)) "buzz"
    1 n
))
(map fizzbuzz (range 1 20))                          
(1 2 "fizz" 4 "buzz" "fizz" 7 8 "fizz" "buzz" 11 "fizz" 13
14 "fizzbuzz" 16 17 "fizz" 19)

Naja, ein Blick in die Code Beispiele der Seite verrät bessere Versionen. Es scheint aber als wären die Katas auch eine gute Möglichkeit um einfach eine Sprache zu lernen, vor allem Dank der Benutzer Lösungen. http://codingkata.org/katas/unit/fizz-buzz/solutions

Mehr über Clojure gibt es hier http://clojure.org/ und in den Screencasts, welche meiner Meinung nach eine sehr schöne Möglichkeit sind etwas über die Sprache zu lernen. http://clojure.blip.tv/posts?view=archive&nsfw=dc

Clojure Erfinder Rich Hickey über Zeit und die Nachteile von OOP

Clojure und Funktionale Programmierung ist für mich derzeit ein sehr interessantes Thema. Von C++ und Java kommend, mit Objekt orientierter Programmierung als state of the art Paradigma, ist die Tatsache, dass Clojure nicht OO ist und es auch gar nicht versucht, zunächst durchaus abstoßend. Ich bin auch noch nicht überzeugt davon, dass komplett davon ab zu kommen richtig ist. Rich Hickey, der Erfinder von Clojure, ist auch der Meinung, dass das Denken in Identitäten für uns Menschen sehr natürlich und verständlich ist und das man dies nicht komplett verwerfen sollte. Dennoch erklärt er, was an unserer derzeitigen Sichtweise falsch ist.

„You cannot step twice into the same river.“ (Heraclitus)

(Der Fluss ist nur ein Konstrukt das wir errichten, er besteht in Wirklichkeit nur aus Wassermolekülen, die zu einem späteren Zeitpunkt allerdings ganz andere sind. Einmal ganz davon abgesehen, dass allein die Tatsache dass die Teilchen sich „geändert“ haben, so etwas wie Zeit erzeugt wird. Mehr dazu aber im Vortrag.)

Ich selber kann den Inhalt, des über eine Stunde dauernden Vortrags, in dieser Kürze sicher nicht wiedergeben und ihr solltet euch lieber selber anhören. Er macht einem einige Dinge bewusst, die einem das Leben im Programmieralltag durchaus erleichtern können. Es handelt sich hierbei nicht direkt um einen Vortrag über Clojure, sondern vielmehr um Grundlagen über die damit Verbunde Herangehensweise. Zugegebenermaßen klingt diese zu Anfang fast schon Philosophisch, was wahrscheinlich nicht von Ungefähr kommt, wie man im Laufe des Videos erfährt. Gegen Ende kommt der Vortrag dann zu Konstrukten und Implementierungsmöglichkeiten, wie sie in Clojure verwendet werden und schließt damit den Kreis zu möglichen Anwendungen. Von sich selber sagt Hickey nämlich er sei ein Pragmatiker; einer der sich sehr gut der Theoretischen Grundlagen bedient, wie ich finde.

http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey

Vielleicht kann man in Zukunft einen Weg finden OO und Funktionale Programmierung zu vereinen. Ich werde mich erst einmal weiter mit Clojure beschäftigen und kann dann vielleicht entscheiden man hier letztendlich bei Spaghetticode landen wird.

GWT – Google-Web-Toolkit, Einführung und Meinung dazu

Ich möchte hier kurz auf einen Artikel eines Kollegen über GWT hinweisen. Dieser befasst sich sehr oberflächlich mit GWT, gibt aber vielleicht eine Motivation sich, ein wenig näher damit zu befassen.

http://blog.seibert-media.net/2010/12/08/gwt-evolution-der-internet-anwendung/

Ich finde es auch sehr angenehm mit GWT zu arbeiten.

Man kommt kaum noch in Berührung mit den syntaktischen Unzulänglichkeiten von Javaskript und kann auf angenehme Weise mächtige und performante “RIA” Anwendungen entwickeln.

Ein Punkt den ich persönlich jedoch wichtig finde ist, dass sich GWT am besten eignet, wenn man tatsächlich Anwendungen entwickelt. Das heißt, anstatt zu versuchen klassische voll designte und dynamische Webseiten damit zu bauen.
Die mitgebrachten Widgets und Layouts kommen nun einmal aus der AWT/Swing Ecke und gliedern sich auch am natürlichsten in solch eine Art Anwendung ein.
Eine voll designte Anwendung, in der man auf das look and feel von Standardelementen zwecks Individualismus verzichtet, ist zwar möglich, bedeutet hier aber etwas mehr Aufwand als bei klassisch Server-Seitig erzeugten HTML Seiten.

Dass solche eine GWT Anwendung dennoch gut aussehen kann, beweist meiner Meinung nach der PostgreSQL GWT Client aus dem GWT Showcase http://demo.teampostgresql.com/

Sehr schön sieht natürlich auch https://www.twentyfeet.com/app/ aus, auch wenn es hier viele klassische Webseiten Elemente gibt, deren Umsetzung aufwändiger ist als bei Server generierten Seiten.

Rome und Felix OSGi

Ich war freudig überrascht, als ich Rome (RSS/Atom syndication and publishing tools) gefunden hatte. Es macht einen soliden, gut designten und dokumentierten Eindruck. Dies und die Tatsache, dass ich ansonsten nichts vergleichbares gefunden habe, ist auch der Grund warum ich so viel Aufwand betrieben habe die Bibliothek zum Laufen zu bekommen.

In unserem Projekt verwenden wir Felix OSGi, was nicht selten zu Problemen bei der Integration von externen Bibliotheken geführt hat.

Im Fall von Rome äußterte sich das in folgenden Exceptions:

SEVERE: Servlet.service() for servlet proxy threw exception
java.lang.NoClassDefFoundError: Could not initialize class com.sun.syndication.feed.synd.SyndFeedImpl
[...]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
[...]

bzw.

SEVERE: Servlet.service() for servlet proxy threw exception
java.lang.NullPointerException
at java.util.Properties$LineReader.readLine(Properties.java:418)
at java.util.Properties.load0(Properties.java:337)
at java.util.Properties.load(Properties.java:325)
at com.sun.syndication.io.impl.PropertiesLoader.(PropertiesLoader.java:74)
at com.sun.syndication.io.impl.PropertiesLoader.getPropertiesLoader(PropertiesLoader.java:46)
at com.sun.syndication.io.impl.PluginManager.(PluginManager.java:54)
at com.sun.syndication.io.impl.PluginManager.(PluginManager.java:46)
at com.sun.syndication.feed.synd.impl.Converters.(Converters.java:40)
at com.sun.syndication.feed.synd.SyndFeedImpl.(SyndFeedImpl.java:56)
[...]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:689)

Letztere Exception tritt auf, weil ein Property File rome.properties nicht gefunden werden kann und dies nicht weiter abgefangen ist.

Versuch 1: Mit diesem Problem brachte mich google zu einigen Leuten die auch das Problem hatten. Es scheint sogar einen Patch zu geben und eine Rome Version (1.0-osgi) im mvn Repository des Autors. Leider hat dies bei mir nicht zu einer Lösung geführt. Quelle und Rome Bugtracking Ticket dazu.

Versuch 2: Interessanterweise stand auf der Rome Seite auch etwas zum Thema Rome + OSGi, worauf mich google nicht geführt hat. Hier ist von einer rome.pluginmanager.useloadclass Property bei RC2 die Rede. Das Setzen der Property auf true hat allerdings auch nicht den gewünschten Effekt gehabt. Der Code der dadurch ausgeführt werden soll sieht auch nicht so aus als würde er helfen. Wer es dennoch versuchen möchte: Rome Homepage : RomeAndOSGi

Lösung: Was letztendlich funktioniert hat, war den Rat von JS Bournival zu befolgen und die Bibliothek selber zu patchen. Dabei muss nicht der Thread ClassLoader verwendet werden, sondern der selbe, der auch verwendet wurde um die Rome Klassen zu laden. Dieser hat dann auch Zugriff auf die Property Files die Rome in der Exception vermisst hat. (Seltsamerweise macht die 1.0-osgi dies angeblich auch so) OSGi: jumping through classoading hoops

Step by Step + Patch:

Ich habe folgendes gemacht:

Rome 1.0 RC2 checkout:

cvs -d :pserver:username@cvs.dev.java.net:/cvs checkout -r v1_0RC2-CORE rome

(Ihr braucht ein java dev Konto, oder falls ihr eures einmal verlegt haben solltet gibt es eine coole Seite bugmenot welche auch für Burger King Gutscheine sehr hilfreich ist.)

grep -sIR "Thread.currentThread().getContextClassLoader()" .

Eine einfache Suche nach der Verwendung des falschen ClassLoaders zeigt die zu Ändernden Klassen auf. Schön zu sehen dass hier auch mit dem bewährten Copy-Paste-Pattern gearbeitet wurde ;-).

Ihr könnte euch das sparen und einfach den Patch anwenden http://gist.github.com/633790

$ cd rome
$ patch -p0 < rome-v1_0RC2-osgi.patch

Das builden mittels mvn install sowie die Tests sollten durchlaufen und das jar kann manuell in euer maven repository installiert werden.

hth