Java calling Clojure. 84

Posted by Uncle Bob Fri, 07 Aug 2009 22:00:43 GMT

While I think Clojure is an interesting language, in order for it to be of real practical use, I must be able to use it in conjunction with other systems I am working on. Specifically, I’d like to write some FitNesse tools in Clojure; but for that to work, I’ll need to call into my Clojure code from Java.

Today, my son Justin and I managed to do just that by following the instruction in Stuart Halloway’s book, the Clojure api website, and Mark Volkmann’s very useful site.

Be advised, that it takes a bit of fiddling to get this to work. You will have to jockey around with your classpaths and output directories. But it’s not actually that hard to do, and the results can be very rewarding.

We implemented the Bowling game (again), but this time we wrote the unit tests in Java, and had them call into Clojure. From the point of view of the Java tests, it looked just like we were calling into java code. The tests had no idea that this was Clojure.

Here are the tests:
package bowling;

import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;

public class BowlingTest {
  private Game g;

  @Before
  public void setup() {
    g = new Game();
  }

  @Test
  public void roll() throws Exception {
    g.roll(0);
  }

  @Test
  public void gutterGame() throws Exception {
    rollMany(20, 0);
    assertEquals(0, g.score());
  }

  private void rollMany(int n, int pins) {
    for (int i=0; i< n; i++) {
      g.roll(pins);
    }
  }

  @Test
  public void allOnes() throws Exception {
    rollMany(20, 1);
    assertEquals(20, g.score());    
  }

  @Test
  public void oneSpare() throws Exception {
    g.roll(5);
    g.roll(5);
    g.roll(3);
    rollMany(17, 0);
    assertEquals(16, g.score());
  }

  @Test
  public void oneStrike() throws Exception {
    g.roll(10);
    g.roll(5);
    rollMany(17,0);
    assertEquals(20, g.score());
  }

  @Test
  public void perfectGame() throws Exception {
    rollMany(12, 10);
    assertEquals(300, g.score());
  }

  @Test
  public void allSpares() throws Exception {
    rollMany(21, 5);
    assertEquals(150, g.score());
  }
}
The clojure code to make them pass looks like this:
(ns bowling.Game
  (:gen-class
    :state state
    :init init
    :methods [
    [roll [int] void]
    [score [] int]
    ]))

(defn -init [] [[] (atom [])])

(defn -roll [this pins]
  (reset! (.state this) (conj @(.state this) pins)))

(declare score-frames)

(defn -score [this]
  (reduce + (take 10 (score-frames [] (conj @(.state this) 0)))))

(defn score-frames [scores [first second third :as rolls]]
  (cond
    (or (empty? rolls) (nil? second) (nil? third)) scores
    (= 10 first) (recur (conj scores (+ 10 second third)) (next rolls))
    (= 10 (+ first second)) (recur (conj scores (+ 10 third)) (nnext rolls))
    :else
    (recur (conj scores (+ first second)) (nnext rolls))))

The magic is all up in that (ns bowling.game… block.

  • The name of the java class is Game in the bowling package, or just bowling.Game.
  • Clojure will create a special member function named state that you can use to squirrel away the state variables of the class.
  • A function named -init will be called when your class is constructed. You must write this function to return a vector containing 1) a vector of all the arguments to pass to the base class constructor (in my case none), and the initial state of the newly created instance, (in my case an empty vector stuffed into an atom)
  • The class will have two new methods, roll, which takes an int and returns void, and score which takes nothing and returns an int.

When a method is called on the instance, Clojure automatically invokes a function of the same name, but prefixed by a -, so -roll and -score are the implementations of the roll and score methods. Note that each of these functions take a this argument. You can get the state out of this by saying (.state this).

From a source code point of view, that’s about all there is to it. But how do you compile this into a java .class file?

Here’s what we did. We created a new file named compile.clj that looks like this:
(set! *compile-path* "../../classes")
(compile 'bowling.Game)
We can run this file from our IDE (IntelliJ using the LAClojure plugin) and it will compile quite nicely. But there are a few things you have to make sure you do.
  • Find out where your IDE puts the .class files, and set the compile-path variable to that directory.
  • Also make sure that directory is in your classpath.
  • Make sure that directory exists!
  • Also make sure that your source file directory (the directory that contains the packages) is in your classpath. (I know… but that’s apparently what it takes.)

You will get errors. And the errors aren’t particularly informative. The key to understanding them is to look at the backtrace of the exceptions they throw. Notice, for example, if the function “WriteClassFile” (or something like that) is buried in the backtrace. If so, you are probably having trouble writing your class file.

In the end, we wrote up an ant script that compiled our clojure and our java together. (You have to compile them in the right order! If java calls Clojure, those .class files have to exist before the java will compile!)

The ant script we used was created for us by IntelliJ, and then we modified it to get it to work. I include it here with the caveat that we made it work, but we didn’t make it “right”. You can ignore most of the stuff at the beginning. The interesting part is the Clojure target, and the clean target.

<?xml version="1.0" encoding="UTF-8"?>
<project name="bowlingforjunit" default="all">

  <property file="bowlingforjunit.properties"/>
  <!-- Uncomment the following property if no tests compilation is needed -->
  <!-- 
  <property name="skip.tests" value="true"/>
   -->

  <!-- Compiler options -->

  <property name="compiler.debug" value="on"/>
  <property name="compiler.generate.no.warnings" value="off"/>
  <property name="compiler.args" value=""/>
  <property name="compiler.max.memory" value="128m"/>
  <patternset id="ignored.files">
    <exclude name="**/CVS/**"/>
    <exclude name="**/SCCS/**"/>
    <exclude name="**/RCS/**"/>
    <exclude name="**/rcs/**"/>
    <exclude name="**/.DS_Store/**"/>
    <exclude name="**/.svn/**"/>
    <exclude name="**/.pyc/**"/>
    <exclude name="**/.pyo/**"/>
    <exclude name="**/*.pyc/**"/>
    <exclude name="**/*.pyo/**"/>
    <exclude name="**/.git/**"/>
    <exclude name="**/.sbas/**"/>
    <exclude name="**/.IJI.*/**"/>
    <exclude name="**/vssver.scc/**"/>
    <exclude name="**/vssver2.scc/**"/>
  </patternset>
  <patternset id="library.patterns">
    <include name="*.zip"/>
    <include name="*.war"/>
    <include name="*.egg"/>
    <include name="*.ear"/>
    <include name="*.swc"/>
    <include name="*.jar"/>
  </patternset>
  <patternset id="compiler.resources">
    <include name="**/?*.properties"/>
    <include name="**/?*.xml"/>
    <include name="**/?*.gif"/>
    <include name="**/?*.png"/>
    <include name="**/?*.jpeg"/>
    <include name="**/?*.jpg"/>
    <include name="**/?*.html"/>
    <include name="**/?*.dtd"/>
    <include name="**/?*.tld"/>
    <include name="**/?*.ftl"/>
  </patternset>

  <!-- JDK definitions -->

  <property name="jdk.bin.1.6" value="${jdk.home.1.6}/bin"/>
  <path id="jdk.classpath.1.6">
    <fileset dir="${jdk.home.1.6}">
      <include name="lib/deploy.jar"/>
      <include name="lib/dt.jar"/>
      <include name="lib/javaws.jar"/>
      <include name="lib/jce.jar"/>
      <include name="lib/management-agent.jar"/>
      <include name="lib/plugin.jar"/>
      <include name="lib/sa-jdi.jar"/>
      <include name="../Classes/charsets.jar"/>
      <include name="../Classes/classes.jar"/>
      <include name="../Classes/dt.jar"/>
      <include name="../Classes/jce.jar"/>
      <include name="../Classes/jconsole.jar"/>
      <include name="../Classes/jsse.jar"/>
      <include name="../Classes/laf.jar"/>
      <include name="../Classes/management-agent.jar"/>
      <include name="../Classes/ui.jar"/>
      <include name="lib/ext/apple_provider.jar"/>
      <include name="lib/ext/dnsns.jar"/>
      <include name="lib/ext/localedata.jar"/>
      <include name="lib/ext/sunjce_provider.jar"/>
      <include name="lib/ext/sunpkcs11.jar"/>
    </fileset>
  </path>

  <property name="project.jdk.home" value="${jdk.home.1.6}"/>
  <property name="project.jdk.bin" value="${jdk.bin.1.6}"/>
  <property name="project.jdk.classpath" value="jdk.classpath.1.6"/>

  <!-- Project Libraries -->

  <!-- Global Libraries -->

  <path id="library.clojure.classpath">
    <pathelement location="/Users/unclebob/projects/clojure-build/lib/ant-launcher.jar"/>
    <pathelement location="/Users/unclebob/projects/clojure-build/lib/ant.jar"/>
    <pathelement location="/Users/unclebob/projects/clojure-build/lib/clojure-contrib.jar"/>
    <pathelement location="/Users/unclebob/projects/clojure-build/lib/clojure.jar"/>
    <pathelement location="/Users/unclebob/projects/clojure-build/lib/commons-codec-1.3.jar"/>
    <pathelement location="/Users/unclebob/projects/clojure-build/lib/commons-fileupload-1.2.1.jar"/>
    <pathelement location="/Users/unclebob/projects/clojure-build/lib/commons-io-1.4.jar"/>
    <pathelement location="/Users/unclebob/projects/clojure-build/lib/compojure.jar"/>
    <pathelement location="/Users/unclebob/projects/clojure-build/lib/hsqldb.jar"/>
    <pathelement location="/Users/unclebob/projects/clojure-build/lib/jetty-6.1.14.jar"/>
    <pathelement location="/Users/unclebob/projects/clojure-build/lib/jetty-util-6.1.14.jar"/>
    <pathelement location="/Users/unclebob/projects/clojure-build/lib/jline-0.9.94.jar"/>
    <pathelement location="/Users/unclebob/projects/clojure-build/lib/servlet-api-2.5-6.1.14.jar"/>
  </path>

  <!-- Modules -->

  <!-- Module BowlingForJunit -->

  <dirname property="module.bowlingforjunit.basedir" file="${ant.file}"/>

  <property name="module.jdk.home.bowlingforjunit" value="${project.jdk.home}"/>
  <property name="module.jdk.bin.bowlingforjunit" value="${project.jdk.bin}"/>
  <property name="module.jdk.classpath.bowlingforjunit" value="${project.jdk.classpath}"/>

  <property name="compiler.args.bowlingforjunit" value="${compiler.args}"/>

  <property name="bowlingforjunit.output.dir" value="${module.bowlingforjunit.basedir}/classes"/>
  <property name="bowlingforjunit.testoutput.dir" value="${module.bowlingforjunit.basedir}/classes"/>

  <path id="bowlingforjunit.module.bootclasspath">
    <!-- Paths to be included in compilation bootclasspath -->
  </path>

  <path id="bowlingforjunit.module.classpath">
    <path refid="${module.jdk.classpath.bowlingforjunit}"/>
    <pathelement location="/Library/junit4.6/junit-4.6.jar"/>
    <path refid="library.clojure.classpath"/>
    <pathelement location="${basedir}/classes"/>
  </path>

  <path id="bowlingforjunit.runtime.module.classpath">
    <pathelement location="${bowlingforjunit.output.dir}"/>
    <pathelement location="/Library/junit4.6/junit-4.6.jar"/>
    <path refid="library.clojure.classpath"/>
    <pathelement location="${basedir}/classes"/>
  </path>

  <patternset id="excluded.from.module.bowlingforjunit">
    <patternset refid="ignored.files"/>
  </patternset>

  <patternset id="excluded.from.compilation.bowlingforjunit">
    <patternset refid="excluded.from.module.bowlingforjunit"/>
  </patternset>

  <path id="bowlingforjunit.module.sourcepath">
    <dirset dir="${module.bowlingforjunit.basedir}">
      <include name="src"/>
    </dirset>
  </path>

  <target name="compile" depends="clojure, compile.java" description="Compile module BowlingForJunit"/>

  <target name="compile.java" description="Compile module BowlingForJunit; production classes">
    <mkdir dir="${bowlingforjunit.output.dir}"/>
    <javac destdir="${bowlingforjunit.output.dir}" debug="${compiler.debug}" nowarn="${compiler.generate.no.warnings}" 
           memorymaximumsize="${compiler.max.memory}" fork="true" executable="${module.jdk.bin.bowlingforjunit}/javac">
      <compilerarg line="${compiler.args.bowlingforjunit}"/>
      <bootclasspath refid="bowlingforjunit.module.bootclasspath"/>
      <classpath refid="bowlingforjunit.module.classpath"/>
      <src refid="bowlingforjunit.module.sourcepath"/>
      <patternset refid="excluded.from.compilation.bowlingforjunit"/>
    </javac>

    <copy todir="${bowlingforjunit.output.dir}">
      <fileset dir="${module.bowlingforjunit.basedir}/src">
        <patternset refid="compiler.resources"/>
        <type type="file"/>
      </fileset>
    </copy>
  </target>

  <target name="clojure">
    <java classname="clojure.lang.Compile">
      <classpath>
        <path location="/Users/unclebob/projects/clojure/BowlingForJunit/classes"/>
        <path location="/Users/unclebob/projects/clojure/BowlingForJunit/src"/>        
        <path location="/Users/unclebob/projects/clojure/BowlingForJunit/src/bowling"/>
        <path location="/Users/unclebob/projects/clojure-build/lib/clojure.jar"/>
        <path location="/Users/unclebob/projects/clojure-build/lib/clojure-contrib.jar"/>  
      </classpath>
      <sysproperty key="clojure.compile.path" value="/Users/unclebob/projects/clojure/BowlingForJunit/classes"/>
      <sysproperty key="java.awt.headless" value="true"/>
      <arg value="bowling.Game"/>
    </java>
  </target>

  <target name="clean" description="cleanup module">
    <delete dir="${bowlingforjunit.output.dir}"/>
    <delete dir="${bowlingforjunit.testoutput.dir}"/>
    <mkdir  dir="${bowlingforjunit.output.dir}"/>
  </target>

  <target name="all" depends="clean, compile" description="build all"/>
</project>
Comments

Leave a response

  1. Avatar
    Hubert Fonseca 6 months later:

    Have you tried using maven?

  2. Avatar
    psn card 7 months later:

    Hah,that was really funny. I even ordered an essay paper on it.These online essay writers made an excellent essay for me.

  3. Avatar
    Kooba Handbags 8 months later:

    Living without an aim is like sailing without a compass. with a new http://www.handbags4buy.com/ idea is a crank until the idea succeeds.

  4. Avatar
    han 8 months later:

    {bowlingforjunit.output.dir}”>

  5. Avatar
    FLV extractor 8 months later:

    this is a good post

  6. Avatar
    VM Ware 9 months later:

    I think Uncle Bob, is in real love with the Clojure language. To improve the practical use of the language he has taken hard efforts. It was interesting to read the magic of bowling game. From the point of view of Java it just looked like that it has been called in Java code. It was difficult to get the idea that it was in Clojure. After reading all this, I got curious and followed the same procedure. I got errors initially. But the errors were not that informative. As Uncle Bob said interesting part is the Clojure target and the clean target.

  7. Avatar
    MKV to iPad 10 months later:

    that real significant changes are often the ones that go unnoticed, because they Make Things Work As They Are Supposed To.

  8. Avatar
    Taoered jeans 11 months later:

    Summer is very hot, who can wear article 7 minutes of pants, must the cowboy oh, the best side or a small beads embroidery that paillette, or color, the best is shallow blue, body parts, the condole belt unlined upper garments grows out of a piece of short sweater, small hollow-out sweater is better, there is colour with cream-colored, white, give priority to, in a few pieces of bright, very pretty, tie-in use: oh!!!!!!!!!!!

  9. Avatar
    Crinoline skirt 11 months later:

    sss femalecostume several popular this year, for your dress reference!

  10. Avatar
    cheap vps about 1 year later:

    sweater, small hollow-out sweater is better, there is colour with cream-colored, white, give priority to, in a few pieces of bright, very pretty, tie-in use: oh!!!!!!!!!!!cheap VPS

  11. Avatar
    supplynflshop about 1 year later:

    good

  12. Avatar
    u shaped desk about 1 year later:

    thanks for the article, it has helped me a lot!

  13. Avatar
    Hosting about 1 year later:

    Wide range of web hosting services are accessible, such as cheap vps , email hosting, Unix hosting, forex vps , Windows hosting, Linux web hosting windows vps etc. We hope you will find a cheap hosting company.

  14. Avatar
    buy custom essays about 1 year later:

    Informative article, thanks!

  15. Avatar
    Industrial paint about 1 year later:

    thanks for shearing the coding.

  16. Avatar
    Dog bark collar about 1 year later:

    Thanks for very informative and useful post. This is what I have been looking for. I really appreciate your post.

  17. Avatar
    used vans for sale about 1 year later:

    Is there a basic introduction to writing class file’s on the site for better understanding.

  18. Avatar
    video to ipad converter about 1 year later:

    best Video Converter for iPad for Converting Video for iPad with high quality. Guide on How to Convert Videos to iPad and Convert Movies to iPad.

  19. Avatar
    Pandora about 1 year later:

    But it’s not actually that hard to do, and the results can be very rewarding.

  20. Avatar
    essays about 1 year later:

    Thanks for sharing such a useful stuff!

  21. Avatar
    map kinase about 1 year later:

    Thanks ,this is is good!

  22. Avatar
    Silicone Molding about 1 year later:

    Mold making is the core business of Intertech (Taiwan). With world level technology, Intertech enjoys a very good reputation for making Injection Mold and Plastic Moldsfor their worldwide customers.

  23. Avatar
    moncler about 1 year later:

    thanks for Moncler Jackets || Christian louboutin UK || Moncler coats || Christian louboutin shoes || Christian louboutin pumps your post!

  24. Avatar
    gearbox about 1 year later:

    We are engaged in gearbox,radial piston motor,axial piston motor,piston motor,slewing transmission,danfoss motor,hydraulic orbital motor,hydraulic steering,hydraulic steering unit,hydraulic winch. All products are strictly tested before delivery by testing bench and comprehensive testing facilities to ensure the quality.

  25. Avatar
    Criminal Check about 1 year later:

    Clojure is really a good language for scripts. This is a great source of stuff, worth reading. Thanks for this awesome information.

  26. Avatar
    Solid State Relay about 1 year later:

    Thanks for writing this blog post, it was informative, enjoyable, and most importantly – a good length!

  27. Avatar
    ghd australia about 1 year later:

    Growth hormone deficiency in Australia, teach you how to protect your hair curl and style hair salon in any way to rectify.

  28. Avatar
    Tenant Screening about 1 year later:

    Ct Credit Bureau offers full tenant screening services to property managers, landlords, and others in the real estate and rental industry.

  29. Avatar
    Criminal Records about 1 year later:

    I got curious and followed the same procedure. I got errors initially. But the errors were not that informative. As Uncle Bob said interesting part is the Clojure target and the clean target.

  30. Avatar
    dswehfhh about 1 year later:

    We are the professional jacket manufacturer, jacket supplier, jacket factory, welcome you to custom jacket.

  31. Avatar
    Sunglass about 1 year later:

    Women Replica Sunglass at cheap discount price

  32. Avatar
    clothing manufacturer about 1 year later:

    unnoticed, because they Make Things Work As They Are Supposed To.

  33. Avatar
    willson about 1 year later:

    Actually this Blog post helped me a lot. I hope you continue writing about this kind of entry.

  34. Avatar
    disney about 1 year later:

    Everyone has different growth process, maybe some feel difficult in his or her childhood memory, or others may think that this is a happy ending. Now, there is a adays boxset hot and popular Disney was growing pains is about growing pains as we all know, different people have different ideas. As such, it tells DVD boxset growing pains, the actor has troubled childhood, but he never gave up Dvd And Movie. Finally, he become a person of success, have a happy family, so like us, we must work harder to study, work harder what be what to write, we also must have a dream, never give up, in the end, we all have a bright future. Tell us a lot of useful things, our whole life whether you have time, you had Disney Dvds better buy the growth process full season, you will DVD benefited.

  35. Avatar
    wholesale hair extensions about 1 year later:

    Christophe (Beverly Hills) Hydrating Curl Spray : it makes curly, dry or damaged hair soft & silky. Also another favorite is “Tres Semme Curl Care European Shaping Milk”

  36. Avatar
    wholesale hair weave about 1 year later:

    Hold lace front firm with both hands, use a wide tooth paddle brush and gently brush your hair system from roots to ends to remove any tangles.

  37. Avatar
    pianoforall about 1 year later:

    Very informative hub, it is wonderful to read. Thank you for sharing. God bless you!

  38. Avatar
    pianoforall about 1 year later:

    Very informative hub, it is wonderful to read. Thank you for sharing. God bless you!

  39. Avatar
    ladders about 1 year later:

    well java is one of my favourite feild, i just wanna thank you for such an awesome blog..

  40. Avatar
    tiffany and co outlet about 1 year later:

    A bad beginning makes a bad ending. A bird in the hand is worth than two in the bush. A year’s plan starts with

    spring. Bad news has wings. Better to ask the way than go astray. By reading we enrich the mind, by conversation we

    polish it. Custom makes all things easy. He is not fit to command others that cannot command himself. He laughs best

    who laughs last. tiffany and co outlet

  41. Avatar
    Sharon Crivello about 1 year later:

    I think i’m going to agree with you on this. We share the same mindset. roofing

  42. Avatar
    www.belstafflondon.com about 1 year later:

    They are fashionable and difficult at travel and out door. belstaff colonial collection goes with well. Our belstaff synthetic belstaff jacket sunglasses withtremendous discounted and free shipping. you could potentially conserve 50%-60% off at our belstaff sale.You must know regarding the manufacturer title men monclerbelstaff jackets in the event that you could potentially be an outdoor enthusiast.

  43. Avatar
    www.belstafflondon.com about 1 year later:

    They are fashionable and difficult at travel and out door. belstaff colonial collection goes with well. Our belstaff synthetic belstaff jacket sunglasses withtremendous discounted and free shipping. you could potentially conserve 50%-60% off at our belstaff sale.You must know regarding the manufacturer title men monclerbelstaff jackets in the event that you could potentially be an outdoor enthusiast.

  44. Avatar
    www.belstafflondon.com about 1 year later:

    They are fashionable and difficult at travel and out door. belstaff colonial collection goes with well. Our belstaff synthetic belstaff jacket sunglasses withtremendous discounted and free shipping. you could potentially conserve 50%-60% off at our belstaff sale.You must know regarding the manufacturer title men monclerbelstaff jackets in the event that you could potentially be an outdoor enthusiast.

  45. Avatar
    www.belstafflondon.com about 1 year later:

    They are fashionable and difficult at travel and out door. belstaff colonial collection goes with well. Our belstaff synthetic belstaff jacket sunglasses withtremendous discounted and free shipping. you could potentially conserve 50%-60% off at our belstaff sale.You must know regarding the manufacturer title men monclerbelstaff jackets in the event that you could potentially be an outdoor enthusiast.

  46. Avatar
    www.belstafflondon.com about 1 year later:

    They are fashionable and difficult at travel and out door. belstaff colonial collection goes with well. Our belstaff synthetic belstaff jacket sunglasses withtremendous discounted and free shipping. you could potentially conserve 50%-60% off at our belstaff sale.You must know regarding the manufacturer title men monclerbelstaff jackets in the event that you could potentially be an outdoor enthusiast.

  47. Avatar
    www.belstafflondon.com about 1 year later:

    They are fashionable and difficult at travel and out door. belstaff colonial collection goes with well. Our belstaff synthetic belstaff jacket sunglasses withtremendous discounted and free shipping. you could potentially conserve 50%-60% off at our belstaff sale.You must know regarding the manufacturer title men monclerbelstaff jackets in the event that you could potentially be an outdoor enthusiast.

  48. Avatar
    www.belstafflondon.com about 1 year later:

    They are fashionable and difficult at travel and out door. belstaff colonial collection goes with well. Our belstaff synthetic belstaff jacket sunglasses withtremendous discounted and free shipping. you could potentially conserve 50%-60% off at our belstaff sale.You must know regarding the manufacturer title men monclerbelstaff jackets in the event that you could potentially be an outdoor enthusiast.

  49. Avatar
    www.belstafflondon.com about 1 year later:

    They are fashionable and difficult at travel and out door. belstaff colonial collection goes with well. Our belstaff synthetic belstaff jacket sunglasses withtremendous discounted and free shipping. you could potentially conserve 50%-60% off at our belstaff sale.You must know regarding the manufacturer title men monclerbelstaff jackets in the event that you could potentially be an outdoor enthusiast.

  50. Avatar
    www.belstafflondon.com about 1 year later:

    They are fashionable and difficult at travel and out door. belstaff colonial collection goes with well. Our belstaff synthetic belstaff jacket sunglasses withtremendous discounted and free shipping. you could potentially conserve 50%-60% off at our belstaff sale.You must know regarding the manufacturer title men monclerbelstaff jackets in the event that you could potentially be an outdoor enthusiast.

  51. Avatar
    www.belstafflondon.com about 1 year later:

    They are fashionable and difficult at travel and out door. belstaff colonial collection goes with well. Our belstaff synthetic belstaff jacket sunglasses withtremendous discounted and free shipping. you could potentially conserve 50%-60% off at our belstaff sale.You must know regarding the manufacturer title men monclerbelstaff jackets in the event that you could potentially be an outdoor enthusiast.

  52. Avatar
    coach bags about 1 year later:

    good post,i like this

  53. Avatar
    belstaff about 1 year later:

    In order to meet all demands, producing belstaff jackets
    never reduce. So many brands in the world conluding North Face jackets, Mens Belstaff Jackets
    , columbia jackets and also spyder belstaff jacket
    , each of them is high quality, workmanship, stylish and comfortable, add waterproof and durable freature, they also support for extreme sports.

  54. Avatar
    okey oyunu oyna about 1 year later:

    useful article. Thanks

    internette görüntülü olarak okey oyunu oyna, gerçek kisilerle tanis, turnuva heyecanini yasa.

  55. Avatar
    Great post, thanks about 1 year later:

    Designer handbags are considered prized possessions by most women all over the world. And phillip lim handbags add class and sophistication to one’s style quotient, giving that extra dose required to make heads turn. Most people all over the world love to own at least one designer brand or another, and strive to fill their wardrobe with collection of big names; be it clothes, designer bags or shoes and boots. phillip lim handbags are especially a favorite with women; who simply go crazy if they can get hold of handbags that are used by celebrities and big shots of the Hollywood industry. In many cases, ladies have gone an extra mile to pay steep prices for designer bags, just because of the brand name. But this is not so with phillip lim handbags. It is quite affordable, and the best part is you get value for money. The exceptional designs, durable quality, unique patterns and great stitching and craftsmanship have all made this brand a name to reckon with. http://www.mona.uwi.edu/">phillip lim handbags change their style very often; but with a Phillip Lim you needn’t worry about changing it every other day since the name in itself creates magic.

  56. Avatar
    Futons Lover about 1 year later:

    I got curious and followed the same procedure. I got errors initially. But the errors were not that informative.

  57. Avatar
    Futons Lover about 1 year later:

    I got curious and followed the same procedure. I got errors initially. But the errors were not that informative.

  58. Avatar
    Movies 2011 about 1 year later:

    Bad news has wings. Better to ask the way than go astray. By reading we enrich the mind, by conversation we

  59. Avatar
    coach purses about 1 year later:

    Mr Coates coach purses is the longest U.S. market popular with one of the most successful leather brand. Mr Coates coach purses store represents the most admirable American fashion innovative style and traditional skills . Mr Coates coach bags have durable quality and exquisite technology, Conspicuous Coach Heels in the female consumers have good reputation. Welcome to our shop Elegant Coach Purses

  60. Avatar
    Jewellery about 1 year later:

    Online UK costume and fashion jewellery shop with,

  61. Avatar
    Hancy about 1 year later:

    Hello Friend,Whichever style of Fashion Shoes you’re looking for, classical, fashionable, lovely or the latest design, you can find your favorite designer shoes in www.dunkpage.com ,several days ago I bought one pair of shoes from there,It’s beautiful and very comfortable!

  62. Avatar
    beats by dr dre headphones about 1 year later:

    I attempted these beats by dr dre studio out in several genres thinking about which i listen to an eclectic mix Beats By Dr Dre. a washing cloth as well as the manual. Do not purchase any beats by dr dre solo purple products inside the internet unless you’re getting from an Authorized internet DealerBeats By Dre Just Solo. We are reliable provide good beats by dr dre pro black by reduced price.

  63. Avatar
    danner boots about 1 year later:

    The ant script we used was created for us by IntelliJ danner boots

  64. Avatar
    danner boots about 1 year later:

    thinking about which i listen to an eclectic danner boots

  65. Avatar
    Crystal Jewellery over 2 years later:

    Great post! Nice and informative, I really enjoyed reading it and will certainly share this post with my friends . Learn everything about what is cubic zirconia

  66. Avatar
    beats by dre store over 2 years later:

    , I really enjoyed reading it and will certainly share this post with my friends . Learn high quality headphones new design headphones

  67. Avatar
    canada goose coat over 2 years later:

    Canada Goose Outlet is Marmot 8000M Parka. The Marmot 8000M Parka is really a waterproof, breathable jacket with 800 fill canada goose jacket feathers. It truly is design and light colored shell is produced for trendy, but uncomplicated, protection from cold temperatures. Reinforced shoulders, elbows and adjustable waist and hem make the Marmot a perfect alternate for skiing and other outdoor sports that want fairly a bit of arm motion. The 8000M Parka weighs three lbs., comes in bonfire and black colours and might be stuffed and stored like a sleeping bag to your convenience.This is one of well-know and prime down jacket brands.Hope our friends like its!Like canada goose womens and Canada Goose Expedition Parka.There are wholesale canada goose.

  68. Avatar
    Tory Burch outlet store over 2 years later:

    It was a beneficial workout for me to go through your webpage

  69. Avatar
    best sleep aid over 2 years later:

    When I at first left a comment I clicked the “Notify me when new comments are added” checkbox and now each time a comment is added I get three notification emails with the same comment. Is there any way you can take away people from that service? Thanks a lot!

  70. Avatar
    MTS ????????? Mac over 2 years later:

    The public may not have known what the messages meant, but it helped pay for them. The skywriting stunt was supported by city and state public funding, according to the High Line’s website. MTS ??? “I wanted a narrative trajectory towards something optimistic at the end, which was the last message, ‘Now Open,’” she said of the work. MTS ??? Mac

  71. Avatar
    Tips For Bowling over 2 years later:

    Great website you have here but I was curious if you knew of any community forums that cover the same topics talked about in this article? I’d really like to be a part of group where I can get responses from other knowledgeable individuals that share the same interest. If you have any suggestions, please let me know. Kudos!

  72. Avatar
    ysbearing/yisong@1stbearing.com over 2 years later:

    Slewing bearing called slewing ring bearings, is a comprehensive load to bear a large bearing, can bear large axial, radial load and overturning moment. http://www.1stbearing.com

  73. Avatar
    christian louboutin over 2 years later:

    The professional design make you foot more comfortable. Even more tantalizing,this pattern make your legs look as long as you can,it will make you looked more attractive.Moveover,it has reasonable price.If you are a popular woman,do not miss it.

    Technical details of Christian Louboutin Velours Scrunch Suede Boots Coffee:

    Color: Coffee
    Material: Suede
    4(100mm) heel
    Signature red sole x

    Fashion, delicate, luxurious Christian louboutins shoes on sale, one of its series is Christian Louboutin Tall Boots, is urbanism collocation. This Christian louboutins shoes design makes people new and refreshing. Red soles shoes is personality, your charm will be wonderful performance.

  74. Avatar
    christian louboutin over 2 years later:

    Great website you have here but I was curious if you knew of any community forums that cover the same topics talked about in this article? I’d really like to be a part of group where I can get responses from other knowledgeable individuals that share the same interest. If you have any suggestions, please let me know. Kudos!

  75. Avatar
    Discount Louboutin Shoes over 2 years later:

    Every women always has Christian Louboutins Wedding Shoes turn of fame but it also has its own goodbyes.

  76. Avatar
    mbtshoe over 3 years later:

    Australia Beats By Dre Studio dr dre beats headphones beats studio beats pro beats solo hd pro headphones music Official store Monster Beats By Dre Pro

  77. Avatar
    music production over 3 years later:

    Thanks for the best blog. It was very useful for me. Keep sharing such ideas in the future as well. This was actually which was looking for and glad to come.

  78. Avatar
    how to make an app,<a href="http://internationalappfactory.com ">how to make an app</a> over 3 years later:

    article really fascinates the core of my interest. I admire the way you brought out the general essence of your topic.

  79. Avatar
    how to make an app over 3 years later:

    article really fascinates the core of my interest. I admire the way you brought out the general essence of your topic.how to make an app

  80. Avatar
    NH Wedding Reception over 3 years later:

    This blog is not only educational but also contains a lot of information. Eager to visit this site again.NH Wedding Reception

  81. Avatar
    Bass fishing tournaments over 3 years later:

    Thanks for posting this useful information. This was just what I was on looking for. I’ll come back to this blog for sure! Bass fishing tournaments

  82. Avatar
    bladeless fans over 3 years later:

    Java calling Clojure. 81 good post67

  83. Avatar
    louboutin sales over 3 years later:

    Java calling Clojure. 82 hoo,good article!!I like the post!161

  84. Avatar
    How To Build Your Own Computer over 3 years later:

    This is great! I have been looking for this, but couldn’t think of the name! Thanks for sharing this post! How To Build Your Own Computer

Comments