用Emacs進行Java開發


用Emacs進行Java開發

1 效果(Ensime做后端,使用JavaFx開發界面)

GIF_2017-04-22_13-02-17.gif

2 Java開發的IDE

2.1 Eclipse和IntelliJ IDEA

Java開發的兩個常用IDE是Eclipse和IntellJ IDEA。其中,Eclipse是一個免費和開源的版本,其他的很多語言的IDE也是使用它,然后,進行修改的。IntelliJ IDEA是一個收費的IDE,據說比Eclipse好用很多。這兩個我都用的不多,Eclipse相對而言還要多一點。

3 Java開發的構建工具

什么是構建工具呢?

最早期的時候,是單文件的項目,根本不需要構建工具,直接編譯那個單文件就可以。當項目變大,變復雜,項目的文件越來越多,然后,出現第一個構建工具:Make,后來,其發展為GNU Make。但是,由於需求的不斷涌現,項目不僅僅只需要編譯,還需要測試、部署等各種任務,各種語言出現了各種各樣的構建工具。
當前,JVM生態圈由三大構建工具所統治:

  • Ant
  • Maven
  • Gradle

3.1 Ant

ANT是最早的構建工具,基於idea,好象是2000年有的,當時是最流行java構建工具,不過它的XML腳本編寫格式讓XML文件特別大。對工程構建過程中的過程控制特別好。

3.2 Maven

Maven它是用來給Ant補坑的,Maven第一次支持了從網絡上下載的功能,仍然采用xml作為配置文件格式,它的問題是不能很好的相同庫文件的版本沖突。Maven專注的是依賴管理,構建神馬的並不擅長。

3.3 Gradle

Gradle屬於結合以上兩個的優點,它繼承了Ant的靈活和Maven的生命周期管理,它最后被google作為了Android御用管理工具。它最大的區別是使用groovy語言作為配置文件格式,不用XML進行配置,使得腳本更加簡潔。

4 既有IDE,何需構建工具?

我們一直搞不懂,既然,已經有Eclipse、IntelliJ IDEA等IDE工具,開發起來,創建項目,然后,點一下run就可以了,非常方便了,還要弄一堆的構建工具出來,麻不麻煩?為什么呢?

覺得應該很多同學有和我一樣的疑惑,所以分享下

1.使用github上的開源項目時是不是經常發現有個叫maven的東西?

2.第一次使用Android studio時是不是要下載一個gradle的玩意?

折騰了一天,想導入下github的客戶端源碼。當然現在還沒成功…各種看不懂的錯誤。郁悶為什么他們弄這些高端玩意干嘛,我們平時eclipse里面不一樣的好好的開發嗎。

作者:Antsdot蟻點
鏈接:https://zhuanlan.zhihu.com/p/23634332
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

同樣,這里也有一個回答:

“一般而言,一個比較正規的項目都不會基於IDE進行構建…一般會用ant, maven, gradle , 為什么不用IDE呢?

首先,是IDE的選擇,有人喜歡,用Vim,Eclipse,IntelliJ IDEA,收費的,免費的.

特別是公開的項目,你用什么IDE 相當於為這個IDE 打廣告了..

所以,一般而言都是用構建工具,而不是IDE .實際上各種IDE 也是基於各種構建系統,也正是不同的IDE,它們的構建方式不同,所以要讓不同的IDE間能一起開發,於是需要一個統一的構建工具,只是你平時不關注而已..

扯到構建工具, 一般c/c++ 項目用make,或者 premake. 而Java 一般是ant,ivy,gradle,maven,還有直接的shell, 是不是很多沒聽說過呢?

所以,去看開源項目就是長見識的時候了…”

來源:http://www.oschina.NET/question/558461_117208

所以,可以這么理解,構建工具是必須的。IDE只是內置了某些構建工具,但是這個工具不一定具有通用性,或者工具的功能不一定強大。為了統一,開發了一套獨立的標准和工具,就是我們所說的構建工具。這些工具,各個IDE也可以使用。

更多構建工具的比較:
http://ensime.org/build_tools/

5 使用Maven進行Java開發

maven 使用 pom.xml 配置文件來進行項目的配置。
所有的庫的最新配置信息,可以從這個網站上查詢到:
https://mvnrepository.com

6 使用Gradle進行Java開發

從上面這么多內容,我們可以知道,從長遠的角度來看,要想項目能夠在更大的范圍內擴展,特別是開源的項目,最好是使用獨立的構建工具來構建項目,那么,Ant、Maven和Gradle應該選哪個呢?

當然是選Gradle了,這個既具有了Ant的靈活性和強大功能,又有Maven的依賴和庫管理,語言groovy又比XML要簡潔和靈活得多。所以,Gradle必然會把這兩個取代,盡管目前,Maven可能還是主流,但不久,應該就是Gradle了。

6.3 Emacs中的Gradle集成

  • 首先,可以創建一個yasnippet:
    # -*- mode: snippet -*-
    # name: build.gradle for springboot
    # key: springboot
    # --
    buildscript {
        ext {
            springBootVersion = '${1:1.5.3.RELEASE}'
        }
        repositories {
            // mavenCentral()
            maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/'}
        }
        dependencies {
            classpath("org.springframework.boot:spring-boot-gradle-plugin:$\{springBootVersion\}")
            // classpath('se.transmode.gradle:gradle-docker:1.2')
        }
    }
    
    allprojects {
        repositories {
            // mavenCentral()
            maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/'}
        }
    }
    
    apply plugin: 'java'
    apply plugin: 'eclipse'
    apply plugin: 'idea'
    apply plugin: 'org.springframework.boot'
    
    group = '${2:com.example}'
    jar {
        baseName = '${3:`(file-name-base (directory-file-name (file-name-directory (buffer-file-name))))`}'
        version =  '0.1.0'
    }
    
    sourceCompatibility = ${4:1.8}
    targetCompatibility = $4
    
    dependencies {
        compile("org.springframework.boot:spring-boot-starter${5:-web}")
        // compile("org.springframework.boot:spring-boot-starter-data-jpa")
        // compile("org.springframework.boot:spring-boot-starter-thymeleaf")
        // compile("com.h2database:h2")
        // compile("mysql:mysql-connector-java")
        testCompile('org.springframework.boot:spring-boot-starter-test')
        compile("org.springframework.boot:spring-boot-devtools")
        compile("junit:junit")
    }
    
    eclipse {
        classpath {
            containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
            containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8'
        }
    }
    
  • 然后,就可以這eshell中,執行
    gradle bootrun
    

    來進行執行了。

  • 自動編譯
    其中,有一點非常有趣,就是自動編譯,當我們做了修改之后,自動編譯,這樣,我們就不需要反復的啟動了。這個這Maven中是可以通過devtools來實現的,但是gradle不支持。后來,中google上找了很久,發現gradle有一個–continuous選項是做這個事情的。
    gradle -t classes processResources
    

    -t 也可以是 –continuous

7 使用sbt進行Scala/Java開發

7.1 安裝

http://www.scala-sbt.org/

然后,在sbt的配置文件夾~/.sbt/中添加文件結構示例(需要手動添加文件夾或者文件):

[-] .sbt
 |--[-] 0.13
 |   |--[-] plugins
 |   |   `----- plugins.sbt
 |   `----- global.sbt
 `----- repositories

7.2 在sbt中安裝sbt-ensime插件

編輯 ~/.sbt/0.13/plugins/plugins.sbt ,並添加:

addSbtPlugin("org.ensime" % "sbt-ensime" % "1.12.5")

7.3 為sbt支持開發版的ensime

編輯 ~/.sbt/0.13/global.sbt

import org.ensime.EnsimeCoursierKeys._
ensimeServerVersion in ThisBuild := "2.0.0-SNAPSHOT"

7.4 在sbt中安裝coursier (有兼容性問題,暫時不用)

7.5 由於大陸連接官方maven庫速度很慢,需要使用國內的鏡像

在~/.sbt/下創建repositories文件,並輸入:

[repositories]
local
# osc: http://maven.oschina.net/content/groups/public/ # 已經不能使用了,使用阿里雲替代
aliyun:http://maven.aliyun.com/nexus/content/groups/public/
maven-central:http://repo1.maven.org/maven2/
store_2:http://repo2.maven.org/maven2/
uk_mir:http://uk.maven.org/maven2/
store_mir:http://mirrors.ibiblio.org/maven2/
typesafe: http://dl.bintray.com/typesafe/ivy-releases/,[organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext], bootOnly
sbt-releases-repo:http://repo.typesafe.com/typesafe/ivy-releases/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
sbt-plugins-repo:http://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]

這樣速度就會快一些。

7.6 Emacs中安裝插件sbt-mode

(use-package sbt-mode
  :commands sbt-start sbt-command
  :init
  (setq
   sbt:prefer-nested-projects t
   sbt:scroll-to-bottom-on-output nil
   sbt:default-command ";compile ;test:compile ;it:compile")
  :config
  ;; WORKAROUND: https://github.com/hvesalai/sbt-mode/issues/31
  ;; allows using SPACE when in the minibuffer
  (substitute-key-definition
   'minibuffer-complete-word
   'self-insert-command
   minibuffer-local-completion-map)

  (bind-key "C-c c" 'sbt-command sbt:mode-map)
  (bind-key "C-c e" 'next-error sbt:mode-map))

7.7 在eshell中鍵入 sbt ,然后,鍵入 ensimeConfig ,創建 .ensime

7.8 在Emacs中執行 ensime 命令就可以啟動后端 ensime server

7.9 自己編譯 ensime server

  • 獲取源代碼
    git clone https://github.com/ensime/ensime-server.git
    
  • 然后,cd 到ensime-server文件夾中
  • 運行 sbt ensimeConfig 產生 .ensime 文件
  • 再執行 compile 進行編譯

8 為什么使用Emacs來開發?

Emacs被稱作是一個操作系統,它可以跨平台,跨語言,只要掌握一個編輯器,就可以覆蓋所有的語言了。有這樣的優勢,實在想不到什么理由不用它來作為開發工具。作為一個編輯器,它擅長的是編輯。對於需要大量解析的工作,它不是不擅長,其實也很擅長,比如CEDET,只是太慢了,對於大型項目,速度始終是個硬傷。
這樣,就需要和其他的工具來進行配合使用。配合使用,就會涉及到交流和溝通的協議。一般的程序,直接把參數,或者字符串傳遞過去,得到返回的字符串就可以了。這是以字符串為傳遞介質。
對於,有些比較復雜的功能,單純的傳遞字符串已經不能滿足需求了。這樣就會有更加復雜的數據結構,來進行傳遞工作。這個數據結構,雙方要能理解,就必須有一個規定,這就是協議。

9 Emacs中的幾款主要Java解釋器或者后端

9.1 jdee(old)

9.2 eclim(eclipse as server)

9.3 meghanada(推薦)

我之前本來試用一下meghanada,結果發現windows下使用不了,就作罷了,轉而使用ensime,但是ensime對scala支持很好,對java很多地方支持得並不好。於是,又硬着頭皮來看meghanada的源代碼,因為既然是java寫的,怎么可能只能在linux運行呢。java本來就是write once, run everywhere的。看完源代碼之后,發現確實是因為文件路徑,linux使用的是"/",而windows是用的"\"導致的,於是提交了代碼,現在linux、Mac和windows下都是可以正常運行的。

9.4 ensime

9.4.1 Introduce

https://coderwall.com/p/avlrna/emacs-ensime-for-your-scala-coding
http://blog.ssanj.net/posts/2011-04-06-ensime-with-emacs.html
構建工具和ensime配置工具,這里要分開來講。一般構建工具和ensime配置插件是使用一套的。但有時,gradle的ensime配置插件過時了,sbt的ensime插件是由官方更新的,所以,總是和ensime配套升級的。所以,用sbt的插件進行配置總是可行的。但是,sbt是一個新的構建系統,所以,在基礎的構建,如對springboot的支持中有時是不穩定的,這時使用Gradle或者Maven會更穩定。
結論:當sbt可以滿足構建需求時,使用sbt是最方便的,既可以配置ensime,又可以構建。當sbt構建出問題時(極少數情況下),這時可以使用Gradle或者Maven來進行構建。
ensime的配置:

9.4.2 sbt(推薦)

http://ensime.org/build_tools/sbt/

  • install
    ~/.sbt/0.13/plugins/plugins.sbt
    addSbtPlugin("org.ensime" % "sbt-ensime" % "1.12.14")
    
    sbt ensimeConfig
    

9.4.3 Maven(配合使用)

http://ensime.org/build_tools/maven/

  • install
    ~/.m2/settings.xml :
    <build>
      <pluginGroups>
        <pluginGroup>org.ensime.maven.plugins</pluginGroup>
      </pluginGroups>
    </build>
    

    國內加速使用阿里雲鏡像,在<build>節點下添加,這樣速度就會快很多倍了:

    <mirrors>
        <mirror>
            <id>alimaven</id>
            <name>aliyun maven</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <mirrorOf>central</mirrorOf>
        </mirror>
    </mirrors>
    
  • use
    mvn ensime:generate
    

9.4.4 Gradle(配合使用)

http://ensime.org/build_tools/gradle/

  • install
    ~/.gradle/init.gradle
    apply plugin: AddEnsimePlugin
    class AddEnsimePlugin  implements Plugin<Gradle> {
      def supportedPlugins = [
        'org.gradle.api.plugins.JavaPlugin',
        'org.gradle.api.plugins.ScalaPlugin',
        'jp.leafytree.gradle.AndroidScalaPlugin'
      ]
    
      void apply(Gradle gradle) {
        def added = false
    
        gradle.allprojects { project ->
          project.with {
            if (parent == null) {
    
              buildscript {
            repositories {
              mavenLocal()
              mavenCentral()
    
                  jcenter()
                }
            //if using snapshot, change rootProject.ensime.serverVersion to a snapshot
            //update this property to the lated ensime-gradle version
                dependencies {
              classpath 'net.coacoas.gradle:ensime-gradle:0.3.0-SNAPSHOT'
            }
              }
            }
    
            plugins.whenPluginAdded { plugin ->
              if (!added && supportedPlugins.contains(plugin.class.name)) {
                rootProject.apply plugin: 'org.ensime.gradle'
            //update the server version to the latest supported by the ensime-gradle plugin
            rootProject.ensime.serverVersion = "2.0.0-SNAPSHOT"
                added = true
              }
            }
          }
        }
      }
    }
    
  • use
    gradle ensime
    

10 Ensime 中常見的操作命令

10.1 sbt ensimeConfig

生成.ensime配置文件

10.2 sbt run

運行整個項目

10.3 sbt core/it:testOnly *JavaCompilerSpec – -z addListener

運行正則表達式匹配的測試用例。

Date: 2017-02-12 20:07

Author: WEN YANG

Created: 2018-06-08 Fri 21:49

Emacs 25.3.1 (Org mode 8.2.10)

Validate


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM