Clojure的Maven配置

先說Clojure

Clojure發音類似”closure”[‘kləʊʒə(r)])],查看了一下官網並沒發現這個名字的由來,也許是閉包的意思。它是JVM中的Lisp,也可以算是現在最實用的Lisp,它可以重用所有的JVM上的庫,在設計上也是很考究,如面向併發設計了STM。而且也有了著名的開源項目Storm。因此,值得慕名而來學習學習,拓展一下思路。

Hello World

去Clojure官網http://www.clojure.org/下載Clojure,最新版本到了1.8。查看了一下可以發現它的目錄如下:
這裏寫圖片描述
其實能用的只有一個clojure-1.8.0.jar。在此目錄下,打開cmd執行Java -cp clojure-1.8.0.jar clojure.main,會得到其REPL界面,就可以進行做實驗了。
這裏寫圖片描述
不過我們使用這個jar只能做點實驗,作爲一個工程要構建、要管理其他的庫、因此得使用構建工具和包管理工具。在Java裏面的實事標準工具是Maven,在Clojure的官方構建工具則叫leiningen。相比起來leiningen比較簡潔,但是我的感覺Clojure更應該作爲一種Java的補充和Java進行混合編程。因此個人更願意使用Maven作爲構建工具和包管理工具。這種策略也是Storm所採用的。

Maven構建

使用Maven構建實際也比較簡單,因爲Maven其實也有一個jar,所以需要引入一個dependency和一個plugin。

<code class="hljs xml has-numbering"><span class="hljs-tag"><<span class="hljs-title">project</span> <span class="hljs-attribute">xmlns</span>=<span class="hljs-value">"http://maven.apache.org/POM/4.0.0"</span> <span class="hljs-attribute">xmlns:xsi</span>=<span class="hljs-value">"http://www.w3.org/2001/XMLSchema-instance"</span>
  <span class="hljs-attribute">xsi:schemaLocation</span>=<span class="hljs-value">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"</span>></span>
  <span class="hljs-tag"><<span class="hljs-title">modelVersion</span>></span>4.0.0<span class="hljs-tag"></<span class="hljs-title">modelVersion</span>></span>

  <span class="hljs-tag"><<span class="hljs-title">groupId</span>></span>org.apache.storm<span class="hljs-tag"></<span class="hljs-title">groupId</span>></span>
  <span class="hljs-tag"><<span class="hljs-title">artifactId</span>></span>test<span class="hljs-tag"></<span class="hljs-title">artifactId</span>></span>
  <span class="hljs-tag"><<span class="hljs-title">version</span>></span>0.0.1-SNAPSHOT<span class="hljs-tag"></<span class="hljs-title">version</span>></span>
  <span class="hljs-tag"><<span class="hljs-title">packaging</span>></span>jar<span class="hljs-tag"></<span class="hljs-title">packaging</span>></span>

  <span class="hljs-tag"><<span class="hljs-title">name</span>></span>test<span class="hljs-tag"></<span class="hljs-title">name</span>></span>
  <span class="hljs-tag"><<span class="hljs-title">url</span>></span>http://maven.apache.org<span class="hljs-tag"></<span class="hljs-title">url</span>></span>

  <span class="hljs-tag"><<span class="hljs-title">properties</span>></span>
    <span class="hljs-tag"><<span class="hljs-title">project.build.sourceEncoding</span>></span>UTF-8<span class="hljs-tag"></<span class="hljs-title">project.build.sourceEncoding</span>></span>
  <span class="hljs-tag"></<span class="hljs-title">properties</span>></span>

  <span class="hljs-tag"><<span class="hljs-title">dependencies</span>></span>
  <span class="hljs-tag"><<span class="hljs-title">dependency</span>></span>
      <span class="hljs-tag"><<span class="hljs-title">groupId</span>></span>org.clojure<span class="hljs-tag"></<span class="hljs-title">groupId</span>></span>
      <span class="hljs-tag"><<span class="hljs-title">artifactId</span>></span>clojure<span class="hljs-tag"></<span class="hljs-title">artifactId</span>></span>
      <span class="hljs-tag"><<span class="hljs-title">version</span>></span>1.6.0<span class="hljs-tag"></<span class="hljs-title">version</span>></span>
   <span class="hljs-tag"></<span class="hljs-title">dependency</span>></span>
   <span class="hljs-tag"></<span class="hljs-title">dependencies</span>></span>
  <span class="hljs-tag"><<span class="hljs-title">build</span>></span>
   <span class="hljs-tag"><<span class="hljs-title">plugins</span>></span>
    <span class="hljs-tag"><<span class="hljs-title">plugin</span>></span>
       <span class="hljs-tag"><<span class="hljs-title">groupId</span>></span>com.theoryinpractise<span class="hljs-tag"></<span class="hljs-title">groupId</span>></span>
       <span class="hljs-tag"><<span class="hljs-title">artifactId</span>></span>clojure-maven-plugin<span class="hljs-tag"></<span class="hljs-title">artifactId</span>></span>
       <span class="hljs-tag"><<span class="hljs-title">extensions</span>></span>true<span class="hljs-tag"></<span class="hljs-title">extensions</span>></span>
       <span class="hljs-tag"><<span class="hljs-title">configuration</span>></span>
          <span class="hljs-tag"><<span class="hljs-title">sourceDirectories</span>></span>
               <span class="hljs-tag"><<span class="hljs-title">sourceDirectory</span>></span>src/main/clj<span class="hljs-tag"></<span class="hljs-title">sourceDirectory</span>></span>
          <span class="hljs-tag"></<span class="hljs-title">sourceDirectories</span>></span>
          <span class="hljs-tag"><<span class="hljs-title">testSourceDirectories</span>></span>
                <span class="hljs-tag"><<span class="hljs-title">testSourceDirectory</span>></span>test/main/clj<span class="hljs-tag"></<span class="hljs-title">testSourceDirectory</span>></span>
           <span class="hljs-tag"></<span class="hljs-title">testSourceDirectories</span>></span>
           <span class="hljs-tag"><<span class="hljs-title">warnOnReflection</span>></span>false<span class="hljs-tag"></<span class="hljs-title">warnOnReflection</span>></span>
           <span class="hljs-tag"><<span class="hljs-title">copyDeclaredNamespaceOnly</span>></span>true<span class="hljs-tag"></<span class="hljs-title">copyDeclaredNamespaceOnly</span>></span>
           <span class="hljs-tag"><<span class="hljs-title">copiedNamespaces</span>></span>
                 <span class="hljs-tag"><<span class="hljs-title">copiedNamespace</span>></span>none<span class="hljs-tag"></<span class="hljs-title">copiedNamespace</span>></span>
           <span class="hljs-tag"></<span class="hljs-title">copiedNamespaces</span>></span>
       <span class="hljs-tag"></<span class="hljs-title">configuration</span>></span>
       <span class="hljs-tag"><<span class="hljs-title">executions</span>></span>
           <span class="hljs-tag"><<span class="hljs-title">execution</span>></span>
               <span class="hljs-tag"><<span class="hljs-title">id</span>></span>compile-clojure<span class="hljs-tag"></<span class="hljs-title">id</span>></span>
               <span class="hljs-tag"><<span class="hljs-title">phase</span>></span>compile<span class="hljs-tag"></<span class="hljs-title">phase</span>></span>
               <span class="hljs-tag"><<span class="hljs-title">goals</span>></span>
                  <span class="hljs-tag"><<span class="hljs-title">goal</span>></span>compile<span class="hljs-tag"></<span class="hljs-title">goal</span>></span>
               <span class="hljs-tag"></<span class="hljs-title">goals</span>></span>
           <span class="hljs-tag"></<span class="hljs-title">execution</span>></span>
       <span class="hljs-tag"></<span class="hljs-title">executions</span>></span>
    <span class="hljs-tag"></<span class="hljs-title">plugin</span>></span>
    <span class="hljs-tag"><<span class="hljs-title">plugin</span>></span>
        <span class="hljs-tag"><<span class="hljs-title">groupId</span>></span>org.apache.maven.plugins<span class="hljs-tag"></<span class="hljs-title">groupId</span>></span>
        <span class="hljs-tag"><<span class="hljs-title">artifactId</span>></span>maven-compiler-plugin<span class="hljs-tag"></<span class="hljs-title">artifactId</span>></span>
        <span class="hljs-tag"><<span class="hljs-title">version</span>></span>3.5.1<span class="hljs-tag"></<span class="hljs-title">version</span>></span>
    <span class="hljs-tag"></<span class="hljs-title">plugin</span>></span>
    <span class="hljs-tag"></<span class="hljs-title">plugins</span>></span>
  <span class="hljs-tag"></<span class="hljs-title">build</span>></span>      
<span class="hljs-tag"></<span class="hljs-title">project</span>></span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li></ul>

需要clojure-maven-plugin來編譯和運行Clojure,最好把java和clojure分開。該plugin的github如下https://github.com/talios/clojure-maven-plugin

比較重要的命令如下

  • clojure:compile
  • clojure:run
  • clojure:repl

要和java混合編譯需要設置exceution

<code class="hljs xml has-numbering"><span class="hljs-tag"><<span class="hljs-title">executions</span>></span>
           <span class="hljs-tag"><<span class="hljs-title">execution</span>></span>
               <span class="hljs-tag"><<span class="hljs-title">id</span>></span>compile-clojure<span class="hljs-tag"></<span class="hljs-title">id</span>></span>
               <span class="hljs-tag"><<span class="hljs-title">phase</span>></span>compile<span class="hljs-tag"></<span class="hljs-title">phase</span>></span>
               <span class="hljs-tag"><<span class="hljs-title">goals</span>></span>
                  <span class="hljs-tag"><<span class="hljs-title">goal</span>></span>compile<span class="hljs-tag"></<span class="hljs-title">goal</span>></span>
               <span class="hljs-tag"></<span class="hljs-title">goals</span>></span>
           <span class="hljs-tag"></<span class="hljs-title">execution</span>></span>
       <span class="hljs-tag"></<span class="hljs-title">executions</span>></span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul>

以下設置在eclipse上可能會有錯誤,主要是

<code class="hljs xml has-numbering"><span class="hljs-tag"><<span class="hljs-title">phase</span>></span>compile<span class="hljs-tag"></<span class="hljs-title">phase</span>></span></code><ul style="" class="pre-numbering"><li>1</li></ul><ul style="" class="pre-numbering"><li>1</li></ul>

的compile的階段問題,但使用maven build沒有問題。默認java編譯會在clojure編譯之前,如果要改變這個循序可以改excecution中的phase標籤。

執行clojure:repl就可以進行測試了,如果混合編程,則需要先執行clojure:compile.建立一個測試Java類

<code class="language-java hljs  has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">JavaInClojure</span> {</span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> index;
    <span class="hljs-keyword">public</span> <span class="hljs-title">JavaInClojure</span>(){
        index = <span class="hljs-number">3</span>;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getIndex</span>(){
        <span class="hljs-keyword">return</span> index;
    }
}</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li></ul>

在建立一個測試clojure模塊

<code class="hljs clojure has-numbering"><span class="hljs-list">(<span class="hljs-title"><span class="hljs-built_in">ns</span></span> clj.test
  <span class="hljs-list">(<span class="hljs-title"><span class="hljs-built_in">import</span></span> org.apache.storm.test.JavaInClojure)</span>)</span>

<span class="hljs-list">(<span class="hljs-title"><span class="hljs-built_in">defn</span></span> hello <span class="hljs-collection">[str]</span>
     <span class="hljs-list">(<span class="hljs-title">println</span> str <span class="hljs-string">",hello world"</span>)</span>
     <span class="hljs-list">(<span class="hljs-title">println</span> <span class="hljs-list">(<span class="hljs-title">.getIndex</span> <span class="hljs-list">(<span class="hljs-title">JavaInClojure.</span> )</span>)</span>)</span>
)</span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li></ul>

執行mvn compile clojure:repl得到一個REPL窗口
這裏寫圖片描述
我們可以看到自己編寫的java類和clojure模塊可以進行混合執行了。

如果改動clojure,可以使用(use clj.test :reload)就可在REPL中執行,如果改動java代碼還得重新編譯。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章