准备工作
安装与配置
vim插件
http://www.vim.org/scripts/script.php?script_id=4298
http://www.quora.com/What-is-the-best-Scala-plugin-for-Vim
https://github.com/derekwyatt/vim-scala
字符编码问题
在默认字符编码为UTF-8的Linux下没问题。
Mac OS X系统的默认字符编码早就改成了UTF-8但它bundle的Java默认字符编码却一直是
MacRoman。在启动REPL时传入参数-Dfile.encoding=UTF-8
。
用vim、emacs或者你习惯的文本编辑器打开scala命令,比如:
$ vim `which scala`
找到如下行:
[ -n "$JAVA_OPTS" ] || JAVA_OPTS="-Xmx256M -Xms32M"
把-D
参数加到JAVA_OPTS
里即可。
Vim插件
实现语法高亮:
到https://github.com/scala/scala-dist上下载,
复制tool-support/src/vim
到.vim
目录下。
neocomplcache
The built-in vim autocomplete isn't great for Scala but the neocomplcache plugin makes typing out long Scala class or package names easier. There is no semantic analysis behind it so all this plugin does is string matching but I was very surprised to realise that this takes you a long way. To me at least it is adequate.
ctags
为了用ctags实现跳转,添加配置文件~/.ctags
:
--langdef=scala --langmap=scala:.scala --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*(private|protected)?[ \t]*class[ \t]+([a-zA-Z0-9_]+)/\4/c,classes/ --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*(private|protected)?[ \t]*object[ \t]+([a-zA-Z0-9_]+)/\4/c,objects/ --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*(private|protected)?[ \t]*case class[ \t]+([a-zA-Z0-9_]+)/\4/c,case classes/ --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*(private|protected)?[ \t]*case object[ \t]+([a-zA-Z0-9_]+)/\4/c,case objects/ --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*(private|protected)?[ \t]*trait[ \t]+([a-zA-Z0-9_]+)/\4/t,traits/ --regex-scala=/^[ \t]*type[ \t]+([a-zA-Z0-9_]+)/\1/T,types/ --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*def[ \t]+([a-zA-Z0-9_]+)/\3/m,methods/ --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*val[ \t]+([a-zA-Z0-9_]+)/\3/l,constants/ --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*var[ \t]+([a-zA-Z0-9_]+)/\3/l,variables/ --regex-scala=/^[ \t]*package[ \t]+([a-zA-Z0-9_.]+)/\1/p,packages/
建立索引时要在当前项目根目录执行:
ctags -R . --exclude=target --exclude=vendor
By default vim will only look for the tags file in the directory of the file
open in the current buffer. If you want vim do move up the directory hierarchy
until it has found the file add this to your ~/.vimrc
:
set tags=tags;/
Now, if you move the cursor over a type name and press Ctrl-]
you will jump to
the definition of the type. That's pretty nifty!
If you want to go back to where you were before the jump press Ctrl-T
.
Sorting of imports
Based on feedback from a collegue who was complaining that my imports always
look messy I have contributed a command to the vim-scala
plugin which
automatically sorts your import statements.
You can invoke the command with :SortScalaImports
and there are two modes on
how your imports could be sorted. By default the command goes through the import
groups (which are defined as separated by a newline) and orders them
alphabetically. This is useful for when you prefer to sort your import into
groups yourself like this:
// Utility imports import com.me import com.them // Concurrency imports import akka.... import scala... import java... import spray.... // Domain imports import com.me.data.... import com.me.data....
The second mode can be enabled by setting the following in your .vimrc
:
let g:scala_sort_across_groups=1
This will take all of your imports and puts them into 3 different groups:
- Java/Scala core libraries
- 3rd party libraries
- First party code, a.k.a your own
What is considered first party code can be configured by setting the a regex. I have set it to this, which is for a standard Play app:
import java.text.SimpleDateFormat import java.util.{ Currency, Locale, UUID, Calendar } import scala.collection.JavaConversions._ import scala.util.Random import play.api._ import play.api.mvc._ import controllers.Secured._ import de.mycompany.useful.library.Class import util._
使用
Scala Shell
使用进入REPL环境的方式:
--(morgan-laptop:pts/8)-(13-03-15 9:04:57)-(~/workspace/study/scala) \-(morgan:%) >>> scala Welcome to Scala version 2.9.2 (OpenJDK 64-Bit Server VM, Java 1.7.0_15). Type in expressions to have them evaluated. Type :help for more information. scala>
Control+a
到行头、Control+e
到行尾,输入回车自动换行。
发现输错了,再按几个回车就退出了。
退出Scala Shell
:exit
或:quit
或:q
在REPL环境中只能一行一行读取,所以如果要换行的话,不能让一行在语法上看起来已经 结束:
scala> if(x > 0) { 1 | } else if(x == 0) 0 else -1 res1: Int = 1
复制代码到REPL
在REPL中输入:paste -raw
粘贴代码,按下Control + D
。
REPL中引入外部文件
也可以在Scala Shell中通过:load
选项导入一个外部的脚本文件,如:
:load script.scala
传递参数给REPL
在系统shell中还可以用参数-e
传递语句与参数给Scala:
$ scala -e "println(\"\"+args(0)+\",\"+args(1))" welcome "hello world" No such file or class on classpath: hello welcome, hello world
脚本
脚本文件,可以接收一个参数并输出欢迎信息:
/* 可以接收一个参数 */ println("Hello, " + args(0) + "!")
调用脚本:scala命令、文件名、参数
--(morgan-laptop:pts/8)-(13-03-14 23:28:27)-(~/workspace/study/scala/tmp) \-(morgan:%) >>> scala helloarg.scala Jade Hello, Jade!
可以通过循环处理多个参数的:
args.foreach( arg => println(arg) )
调用:
--(morgan-laptop:pts/8)-(13-03-14 23:49:39)-(~/workspace/study/scala/tmp) \-(morgan:%) >>> scala pa.scala Scala is even more fun Scala is even more fun
Scala会把脚本放到一个名为Main
类中的main()
方法里,可以用-savecompiled
选项
来生成Jar文件查看生成的字节码。
如果有多个脚本文件,scala会默认在同一目录中所有的文件中查找需要的类;如果有需要
的文件在不同的目录里,可以在sourcepath
参数中指定要查找的目录:
$ scala -sourcepath .:module1:module2 myApp.scala
如果需要的脚本里的内容已经编译过了,可以不编译这些脚本。如果生成的字节码不在当前
目录下要用classpath
指定类文件的位置就可以了,-d
表示字节码存放的位置:
$ scala -d . -classpath .:module1:module2 myApp.scala
OS可执行脚本
Unix下可执行脚本:
#!/bin/sh exec scala "$0" "$@" !# println("hello," + arg(0) + "!")
执行:
$ chmod +x helloarg $ ./helloarg globe
Windows下可执行脚本:
::#! @echo off call scala %0 %* goto :eof ::!# println("hello," + arg(0) + "!")
执行:
> helloarg.bat globe
Scala程序
main方法
先看一个工具类,它根据字符串来计算出检验和:
import scala.collection.mutable.Map class ChecksumAccumulator { private var sum = 0 def add(b: Byte) { sum += b } def checksum(): Int = ~(sum &0xFF) + 1 } object ChecksumAccumulator { private val cache = Map[String, Int]() def calculate(s: String): Int = if( cache.contains(s) ) { cache(s) } else { val acc = new ChecksumAccumulator for (c <- s) acc.add(c.toByte) val cs = acc.checksum() cache += (s -> cs) cs } }
然后是主程序。独立运行的程序一定要有main
方法(仅有一个参数Array[String]
而且
结果类型为Unit
)的单例对象。
import ChecksumAccumulator.calculate object Summer { def main(args: Array[String]) { for (arg <- args) println(arg + " -> " + calculate(arg)) } }
编译Scala程序:
--(morgan-laptop:pts/8)-(13-03-15 0:28:39)-(~/workspace/study/scala/tmp) \-(morgan:%) >>> scalac ChecksumAccumulator.scala Summer.scala
有一个fast Scala compiler
的后台进程可以在第一次被调用后一直跑在后台,
节省一下每次编译的速度:
--(morgan-laptop:pts/8)-(13-03-15 0:29:11)-(~/workspace/study/scala/tmp) \-(morgan:%) >>> fsc ChecksumAccumulator.scala Summer.scala
可以关掉这个后台进程:
--(morgan-laptop:pts/8)-(13-03-15 0:29:11)-(~/workspace/study/scala/tmp) \-(morgan:%) >>> fsc -shutdown
编译完后可以看到生成的.class
文件:
--(morgan-laptop:pts/8)-(13-03-15 0:44:31)-(~/workspace/study/scala/tmp) \-(morgan:%) >>> ls *.class ChecksumAccumulator$$anonfun$calculate$1.class ChecksumAccumulator$.class Summer.class ChecksumAccumulator.class Summer$$anonfun$main$1.class Summer$.class
运行编译出来的类文件:
--(morgan-laptop:pts/8)-(13-03-15 0:30:58)-(~/workspace/study/scala/tmp) \-(morgan:%) >>> scala Summer of love of -> -213 love -> -182
使用jdb调试main方法
简单的例子:
object hello { def main(args: Array[String]): Unit = { println("Hello, world!") var a = 10 var b = 20 var c = a + b println(c) var d = 1 + a; if(d == 11) { println("aaaaaaaaa") } } }
编译:
$ scalac -g:vars hello.scala $ ls hello.class 'hello$.class' hello.scala
scala程序会包含scala的jar包,但是java程序要指定scala的jar包位置:
$ scala hello Hello, world! 30 aaaaaaaaa $ java -cp ./:/$SCALA_HOME/lib/scala-library.jar hello Hello, world! 30 aaaaaaaaa
所以使用jdb时,也要指定scala的jar包位置:
jdb -classpath ./:/$SCALA_HOME/lib/scala-library.jar hello Initializing jdb ... > stop in hello.main Deferring breakpoint hello.main. It will be set after the class is loaded. >
因为main方法在object对象中,所以断点打在hello.main
方法中是没有用的:
> stop in hello.main Deferring breakpoint hello.main. It will be set after the class is loaded. > run run hello Set uncaught java.lang.Throwable Set deferred uncaught java.lang.Throwable > VM Started: Set deferred breakpoint hello.main Breakpoint hit: "thread=main", hello.main(), line=-1 bci=0 main[1] locals Local variable information not available. Compile with -g to generate variable information main[1]
断点要打在hello$.main
方法上:
> stop in hello$.main Deferring breakpoint hello$.main. It will be set after the class is loaded. > run run hello Set uncaught java.lang.Throwable Set deferred uncaught java.lang.Throwable > VM Started: Set deferred breakpoint hello$.main Breakpoint hit: "thread=main", hello$.main(), line=3 bci=0 3 println("Hello, world!") main[1] locals Method arguments: args = instance of java.lang.String[0] (id=485) Local variables: main[1] list 1 object hello { 2 def main(args: Array[String]): Unit = { 3 => println("Hello, world!") 4 var a = 10 5 var b = 20 6 var c = a + b 7 println(c) 8 9 var d = 1 + a; 10 if(d == 11) { main[1]
App特质
扩展App
特质,然后把程序代码放入构造器方法中:
object Hello extends App { print("Hello World!") }
通过args
属性得到命令行参数:
object Hello extends App { if (args.length > 0) println("Hello, " + args(0)) else println("Hello, World!") }
在调用程序时设置了参数scala.time
的话,程序退出时还会显示消耗的时间:
$ scalac Hello.scala $ scala -Dscala.time Hello Fred Hello, Fred [total 4ms]
原理是App
特质是扩展自DelayedInit
,它会把初始化方法都挪到delayedInit()
方法
中。在那里有显示初始化时间的动作。
Application特质
还有一个早期版本的方法:Application
特质的方式实现应用程序,但是有局限:
- 在静态初始化方法中执行程序动作,不被编译器优化;
- 不能访问命令行参数;
- 只能在单线程下用。
所以不推荐用它。
形式类似于:
object MyApp extends Application { println("Hello") }
脚本与程序的区别
脚本必须以表达式结束,而程序以定义结尾。尝试以scala
解释器运行程序会报错。
构建工具
Ant任务
相关的Ant任务有scalac
、fsc
和scaladoc
,这里只介绍scalac
。
scala.home=/opt/morganstudio/language/scala compile.version=1.7 deploy.name=scala-example
<?xml version="1.0" encoding="UTF-8"?> <project name="scala-example" default="init" basedir="."> <description>scala example</description> <property file="build.properties" /> <property name="sources.dir" value="sources" /> <property name="build.dir" value="build" /> <target name="init"> <property name="scala-library.jar" value="${scala.home}/lib/scala-library.jar" /> <path id="build.classpath"> <pathelement location="${scala-library.jar}" /> <pathelement location="${build.dir}" /> </path> <taskdef resource="scala/tools/ant/antlib.xml"> <classpath> <pathelement location="${scala.home}/lib/scala-compiler.jar" /> <pathelement location="${scala-library.jar}" /> </classpath> </taskdef> </target> <target name="build" depends="init"> <mkdir dir="${build.dir}" /> <scalac srcdir="${sources.dir}" destdir="${build.dir}" classpathref="build.classpath"> <include name="**/*.scala" /> </scalac> </target> <target name="run" depends="build"> <java classname="Summer" classpathref="build.classpath"> </java> </target> </project>
以后可能会用到的jar包还有scala-actors.jar
和scala-dbc.jar
.
maven构建
相关文档:http://davidb.github.io/scala-maven-plugin
https://www.assembla.com/wiki/show/scala-ide/With_M2Eclipse
- 注意不同版本的Scala字节码有差异,所以要指明版本。
-
加入了插件以后要指定版本,如果不清楚的话调用时加上
-U
选项。
archetype:generate
mvn archetype:generate \ -DarchetypeGroupId=org.scala-tools.archetypes \ -DarchetypeArtifactId=scala-archetype-simple \ -DremoteRepositories=http://scala-tools.org/repo-releases \ -DgroupId=me.arganzheng.study.scala \ -DartifactId=scala-helloworld \ -Dversion=1.0-SNAPSHOT
一个简单的例子:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.scala-lang.demo</groupId> <artifactId>scala-test</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>Demo of maven for Scala Lang website</name> <url>http://scala-lang.org</url> <properties> <scala.version>2.10.2</scala.version> </properties> <build> <sourceDirectory>src/main/scala</sourceDirectory> <testSourceDirectory>src/test/scala</testSourceDirectory> <plugins> <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <version>3.1.5</version> <executions> <execution> <goals> <goal>compile</goal> <goal>testCompile</goal> </goals> </execution> </executions> <configuration> <scalaVersion>${scala.version}</scalaVersion> </configuration> </plugin> </plugins> </build> </project>
对于无用的警告信息「Multiple Versions of Scala Libraries Detected」
可通过scalaCompatVersion
参数去掉:
<plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <version>3.1.6</version> <configuration> <scalaCompatVersion>${scala.binary.version}</scalaCompatVersion> <scalaVersion>${scala.version}</scalaVersion> </configuration> <!-- other settings--> </plugin>
Where in my case I have scala.binary.version
property defined as
<scala.binary.version>2.10</scala.binary.version>
内存参数配置
<project> ... <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <version>3.1.5</version> <executions> <execution> <goals> <goal>compile</goal> <goal>testCompile</goal> </goals> </execution> </executions> <configuration> <jvmArgs> <jvmArg>-Xms64m</jvmArg> <jvmArg>-Xmx1024m</jvmArg> </jvmArgs> </configuration> </plugin> ... </project>
编译开关
<project> ... <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <version>3.1.5</version> <configuration> <args> <arg>-unchecked</arg> <arg>-deprecation</arg> <arg>-explaintypes</arg> </args> </configuration> </plugin> ... </project>
使用本地的scala's jar
可以不用maven库里的scala版本而是本地scala.home
变量指定的版本。但不要这样部署
与安装,这样会搞坏工程的。这里用到了:
-
${scala.home}/lib/scala-library.jar
-
${scala.home}/lib/scala-compiler.jar
mvn compile -Dscala.home=<path/of/scalaHome>
运行
运行Scala程序
直接指定类启动,不需要在pom文件中定义启动器:
mvn scala:run -DmainClass=Example -DaddArgs="arg0|arg2|arg3|arg4"
还可以指定一个启动器加上更多的参数信息:
定义Scala语言依赖;定义启动器指定运行类与id、参数,启动器可以有多个
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.scala-lang.demo</groupId> <artifactId>scala-test</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>Demo of maven for Scala Lang website</name> <url>http://scala-lang.org</url> <properties> <scala.version>2.10.2</scala.version> </properties> <dependencies> <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-library</artifactId> <version>2.10.2</version> </dependency> </dependencies> <build> <sourceDirectory>src/main/scala</sourceDirectory> <testSourceDirectory>src/test/scala</testSourceDirectory> <plugins> <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <version>3.1.5</version> <configuration> <scalaVersion>${scala.version}</scalaVersion> <launchers> <launcher> <id>foo</id> <mainClass>Example</mainClass> <args> <arg>Hello</arg> <arg>World</arg> </args> </launcher> </launchers> </configuration> </plugin> </plugins> </build> </project>
指定启动器id启动:
mvn scala:run -Dlauncher=foo
scala console
http://scala-tools.org/mvnsites/maven-scala-plugin/usage_console.html
运行单元测试
导入ScalaTest与Junit包;定义编译测试任务;
<dependencies> <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-library</artifactId> <version>2.10.2</version> </dependency> <dependency> <groupId>org.scalatest</groupId> <artifactId>scalatest_2.10</artifactId> <version>1.9.1</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency> </dependencies> <build> <sourceDirectory>src/main/scala</sourceDirectory> <testSourceDirectory>src/test/scala</testSourceDirectory> <plugins> <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <version>3.1.5</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.12</version> </plugin> </plugins> </build>
不过我测试中好像surefire插件一段不加上也能启用sufire任务。
在Scala程序里@RunWith
注解让surefire能找到继承自FunSuite
的测试类:
package com.tysonhamilton.scalatest.test import org.scalatest.junit.JUnitRunner import org.scalatest.FunSuite import org.junit.runner.RunWith @RunWith(classOf[JUnitRunner]) class TestUnitTest extends FunSuite { test("TwoPlusTwo") { val twoPlusTwo = 2 + 2 assert(twoPlusTwo == 4) } }
运行的命令:
-
maven:clean
-
scala:compile
-
scala:testCompile
-
surefire:test
还可以把测试用例的编译与运行放到Maven的生命周期中去:
<build> <sourceDirectory>src/main/scala</sourceDirectory> <testSourceDirectory>src/test/scala</testSourceDirectory> <plugins> <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <version>3.1.5</version> <executions> <execution> <id>compile-scala</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> </execution> <execution> <id>compile-tests-scala</id> <phase>compile</phase> <goals> <goal>testCompile</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.12</version> <executions> <execution> <id>surefire-test</id> <phase>test</phase> <goals> <goal>test</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
这样就并到三个周期里去了:
-
maven:clean
-
maven:compile
-
maven:test
生成API Doc
-
mvn scala:doc
构建混合Java与Scala
<build> <pluginManagement> <plugins> <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <version>3.1.5</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.0.2</version> </plugin> </plugins> </pluginManagement> <plugins> <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <executions> <execution> <id>scala-compile-first</id> <phase>process-resources</phase> <goals> <goal>add-source</goal> <goal>compile</goal> </goals> </execution> <execution> <id>scala-test-compile</id> <phase>process-test-resources</phase> <goals> <goal>testCompile</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <executions> <execution> <phase>compile</phase> <goals> <goal>compile</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
sufire结合ScalaTest测试
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <includes> <include>**/*Tests.java</include> </includes> <excludes> <exclude>**/Abstract*.java</exclude> </excludes> </configuration> </plugin> </plugins> </build>
运行指定的测试类:
mvn test -Dtest=[ClassName]
[ClassName]
为要运行的测试类的类名(不要带扩展名),多个测试类间用逗号连接即可,
类名支持*
通配符,范例:
mvn test -Dtest=MyClassTest
mvn test -Dtest=MyClass1Test,MyClass2Test
mvn test -Dtest=MyClass*Test,YourClassTest
mvn test -Dtest=MyClassTest
运行测试类中指定的方法:(这个需要maven-surefire-plugin:2.7.3以上版本才能支持)
mvn test -Dtest=[ClassName]#[MethodName]
[MethodName]
为要运行的方法名,支持*
通配符,范例:
-
mvn test -Dtest=MyClassTest#test1
-
mvn test -Dtest=MyClassTest#*test*
sbt
配置国内代理库
感谢 OSChina 提供了 Maven Center 的镜像, 配置添加它有助于提升下载速度.
[repositories] local oschina:http://maven.oschina.net/content/groups/public/
若你知道其他更快的镜像库, 同上配置. 一般互联网企业部署了供内部使用的镜像库(如 nexus ), 也可以配置于此.
兼容 Ivy 路径布局
大多数中心仓库(repository)是 Maven 的路径布局, 这就导致 SBT 的插件和部分 Ivy 依赖无法从其下载.
[repositories] local oschina:http://maven.oschina.net/content/groups/public/ oschina-ivy:http://maven.oschina.net/content/groups/public/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
精简 url 列表
远程仓库越多越全, 可以基本避免下载不到的问题. 但是, 也可能让下载的时间更长, 让你不愿在等待而放弃下载.
因为, 下载过程中 SBT 会串行的 "询问" 列表中所有的远程仓库, 无论是否找得到.
当依赖树越大, 整个下载的过程就更漫长. 若再遇到响应慢的仓库, 情况恶化的令人发指.
推荐列表策略是:
- 本地仓库
- 国内(或内网)镜像仓库
-
国外官方仓库, 通常
#
注释掉, 待上面不管用时, 去掉#
再做尝试
上面办法不管用
建议使用你熟悉的网络嗅探手段查清具体原因, 对症下药了.
一个可行的方案
- 下载 HTTP 代理工具 mitmproxy, 并运行它
-
启动 SBT时, 附加参数
-Dhttp.proxyHost=loalhost -Dhttp.proxyPort=8080
, 这会将 SBT 所有的 HTTP 请求经由 mitmproxy转发 - 通过 mitmproxy 来分析 HTTP 请求失败的具体原因
eclipse
maven里增加scala模板:
「preferences」>「Maven」>「Archetypes」>「Add Remote Catalog」
http://repo1.maven.org/maven2/archetype-catalog.xml
新建Archetype:
Group Id: net.alchim31.maven Artifact Id: scala-archetype-simple Version:1.5
以后新建Maven项目,选这个Archtype就可以了。
Install the m2eclipse-scala plugin
There is a configurer for m2eclipse that will setup Scala projects for you. You can install it using the directions here: