先讲一句大实话:在mac上装Scala,网上教程十篇有八篇是Windows视角或者两三年前的旧流程,Apple Silicon芯片普及以后,很多老命令、老路径直接失效,照着抄大概率会在某个步骤卡死。我见过太多人在终端敲完scala -version没反应,或者在IDEA里新建项目时找不到Scala SDK,然后在群里反复问同一个问题。这件事的真正难点不在Scala本身,而在JDK环境、构建工具、IDE插件这三层链路是否完整打通。
这篇教程就是冲着"一条龙跑通"去的:从JDK安装到Scala本体,再到IDEA里的Scala插件,最后新建项目并跑出Hello World。适合刚接触Scala、准备在mac上搭环境的新手,也适合之前装过但一直没跑通、想回头理清思路的人。我会把常见的坑也一并讲清楚,尽量让你少走弯路。
1. 为什么要先把JDK理顺:Scala的一切都跑在JVM上
1.1 Scala和JDK的关系,以及版本怎么选
很多人上来就直接搜"Scala安装",跳过了JDK这一步,这是最典型的翻车原因。Scala这门语言的定位很明确:它是一门跑在JVM上的语言。你写好的Scala代码,scalac编译器会把它编译成.class字节码,再由JVM解释执行。也就是说,没有JDK,Scala连编译的第一步都走不出去。
这里要区分一下JDK和JRE:JRE是运行环境,JDK是开发环境。日常我们说的"装个Java环境",指的是装JDK。JDK里包含了JRE、编译器javac,以及一堆开发工具。Scala编译器虽然不叫javac,但它本质上是运行在JVM上的一个Java程序,所以必须先有一个完整的JDK兜底。
再就是版本选择。Scala对JDK版本的兼容性没有Java那么敏感,但选错版本同样会出问题:
| JDK版本 | 适用场景 | 个人建议 |
|---|---|---|
| JDK 8 | 老项目、部分Spark/Hadoop生态依赖 | 不是新项目首选,除非公司项目要求 |
| JDK 11 | 过渡版本,部分企业仍在用 | 可用,但没有明显优势 |
| JDK 17 | 当前主流LTS版本,Scala 2.13和3.x都支持良好 | 个人开发学习,直接选这个 |
| JDK 21 | 最新LTS,新特性更多 | 想尝鲜可以用,但要注意个别旧工具链兼容性 |
我给新手的建议很直白:装JDK 17。它是LTS(长期支持)版本,Scala 2.13.x和Scala 3.x都能稳定运行,IDEA也能正常识别。没必要为了追求新版本去装JDK 21,搭环境追求的是"稳",不是"新"。
1.2 三种装JDK的方式,我推荐你走哪条
mac上装JDK的常见方式有三种:Homebrew、官方安装包、SDKMAN。
Homebrew安装:
brew install openjdk@17装完以后会有一句提示,说这个包是"keg-only"的,意思是你需要手动把它链接到系统路径里。很多新手就是漏掉了这一步,导致java -version死活没反应。
官方安装包(Oracle JDK 或 Adoptium Temurin):
去Oracle官网或者Adoptium官网下载dmg/pkg安装包,双击安装,图形化操作最简单。但缺点是后续想切换JDK版本很麻烦,每次都得手动改环境变量。
SDKMAN:
这是我个人最推荐的方式。SDKMAN是一个命令行工具,专门用来管理JVM生态的各种SDK版本,Java、Scala、sbt、Gradle都能用它装。安装SDKMAN本身只需要一条命令:
curl -s "https://get.sdkman.io" | bash装完之后新开一个终端窗口,执行:
sdk list java列出可用的Java发行版,然后安装:
sdk install java 17.0.13-temtem是Temurin发行版,也就是Eclipse Adoptium项目维护的OpenJDK构建,免费、干净、没有Oracle那种许可上的历史包袱。
为什么我更推荐SDKMAN?因为后面装Scala和sbt还得继续折腾。用SDKMAN之后,sdk install scala、sdk install sbt都是同一套逻辑,版本切换、卸载都很干净。比起Homebrew那套"装了还得手动link"的流程,SDKMAN在mac上的体验好很多。
1.3 JAVA_HOME的坑:终端能用,IDEA不一定认账
JDK装好以后,第一件事是确认它在终端里可用。执行:
java -version如果显示了版本信息,再检查JAVA_HOME:
echo $JAVA_HOMEmac上有一个很实用的定位工具,/usr/libexec/java_home,它会帮我们找到系统里JDK的安装路径。在~/.zshrc里写入:
export JAVA_HOME=$(/usr/libexec/java_home -v 17)然后启用配置:
source ~/.zshrc这里要提前打个预防针:mac默认shell是zsh,配置文件是~/.zshrc,不是Linux常用的~/.bashrc。网上很多教程还在让人改~/.bash_profile,在mac上压根不会被读取,这就是很多人配置完环境变量没效果的根源之一。
更隐蔽的一个坑是:即使你在终端里测试java -version正常,IDEA从Finder里点击启动时,可能依然找不到JDK。原因在于macOS的GUI应用不读取shell的配置文件,它继承的是窗口环境那套环境变量。也就是说,IDEA并不知道你在~/.zshrc里设置了什么。这个问题的解法后面讲IDEA配置时会专门说,这里先记住结论:终端环境变量和GUI应用环境变量,在mac上是两套体系。
2. 正式安装Scala与sbt:brew和手动两条路各自怎么走
2.1 一行brew install scala的背后,隐藏了哪些信息
如果你图省事,装了Homebrew之后,可以直接执行:
brew install scala以及顺手把sbt也装掉:
brew install sbt装完后验证:
scala -version scalac -version sbt --version这三条命令如果都能输出版本号,说明Scala核心工具链已经通了。
不过得说清楚brew install scala到底装了什么。它安装的是Scala官方的编译器、标准库和REPL(交互式命令行),但不包含也永远不会包含sbt——sbt是独立项目。另外,Homebrew仓库里的Scala版本更新有一定滞后性,比如Scala 3.x新版本发布了,brew可能要过一段时间才会同步。对学习用途来说这没问题,但如果你需要精确控制Scala版本(比如某个框架强制要求2.13.x的某个小版本),那brew的灵活性就不够了。
2.2 手动安装Scala:不建议新手做,但你要知道备用方案
有些场景下你大概率需要手动安装:公司内网环境用不了brew、需要特定Scala版本、或者你想把Scala装到自定义目录。手动安装的流程也不复杂,先去Scala官网的下载页,找到对应版本的tgz压缩包链接,比如2.13.x系列的生产版本。
下载后解压到你的某个目录,比如~/tools下:
cd ~/tools tar -xzf scala-2.13.x.tgz然后在~/.zshrc里配置PATH:
export SCALA_HOME=~/tools/scala-2.13.x export PATH="$SCALA_HOME/bin:$PATH"重新加载配置后,执行scala -version验证。
关于版本选择,这里多聊两句。Scala目前有2.13和3.x两个大版本线并行。2.13是过去十年Scala生态的主力,Spark等大数据框架都是基于Scala 2.12/2.13构建的;3.x是新一代Scala,语法更简洁,但不少旧库迁移还没完全跟上。我的建议是:如果你是为了Spark、大数据方向学Scala,装2.13;如果是为了学语言本身、写新项目,装3.x也完全可行。IDEA对这两个版本的支持都没问题。第一次搭环境的人,装一个2.13.x更稳,因为后面配sbt、配Spark等生态时兼容性问题更少。
2.3 顺手装好sbt,并给sbt配置国内镜像
sbt是Scala社区最主流的构建工具,地位相当于Java的Maven或Gradle。IDEA创建Scala项目时,默认就会用sbt作为构建后端。所以不要只装Scala,sbt也要一起装好。
用brew装是最省事的:
brew install sbt装完之后,有一个立刻要做的事:配置国内镜像。否则你第一次在IDEA里创建sbt项目时,sbt会尝试从Maven Central和Typesafe仓库下载一大堆依赖,那个速度会让你怀疑人生,甚至直接卡在"Resolving..."状态十几分钟不动。
镜像配置的路径在~/.sbt/repositories,没有这个文件就新建一个,内容参考:
[repositories] local aliyun-maven: https://maven.aliyun.com/repository/public aliyun-central: https://maven.aliyun.com/repository/central typesafe-releases: https://repo.typesafe.com/typesafe/releases maven-central: https://repo1.maven.org/maven2/解释一下这个文件的原理:sbt通过一组resolver(解析器)来定位依赖,默认优先走官方仓库。我们写入这个文件后,sbt会先访问本地仓库,再走阿里云镜像,最后才走官方源。这样大部分常用依赖都会命中镜像,速度快很多。
配置完成后,可以在命令行先触发一次sbt初始化,让镜像配置生效,并顺便预热一下依赖缓存。在任何一个目录下执行sbt,进入sbt交互界面后输入exit退出即可。第一次启动会下载sbt自身的组件,耐心等它跑完。后面在IDEA里建项目,就不会再卡在这一步了。
3. IDEA里的Scala插件:从Marketplace到离线安装的完整链路
3.1 先认清IDEA和Scala插件的关系
IDEA本身不解析Scala语法,它靠插件来提供Scala的语法高亮、自动补全、编译运行等功能。Scala插件是JetBrains官方维护的插件,在IntelliJ IDEA的社区版(Community Edition)和终极版(Ultimate Edition)上都可以安装使用。
关于IDEA版本的选择,我个人建议:学习Scala完全没有必要用Ultimate版的激活和破解方案,社区版就足够了,免费、干净、没有法律风险。IDEA的社区版功能已经覆盖了Scala开发的核心需求:代码补全、语法高亮、运行调试、sbt支持,全都内置在免费版本里。那些纠结"IDEA要不要破解"的时间,不如省下来多写两行代码。
还有一点要提醒:IDEA插件和Scala SDK是两回事。插件是IDEA的功能模块,决定IDE能不能识别并运行Scala代码;Scala SDK是Scala编译器和标准库的存在。两者缺一不可,后面建项目时还会再遇到。
3.2 Marketplace安装与连不上时的替代方案
IDEA里安装Scala插件的常规流程:
打开IDEA,进入Preferences(快捷键Cmd + ,),选择Plugins,然后打开Marketplace标签页,在搜索框输入Scala,找到由JetBrains发布的Scala插件(发布者显示为JetBrains),点击Install按钮。安装完成后,IDEA会提示重启,点击Restart IDE即可。
重启之后,你可以在Plugins页面的Installed标签里看到Scala,确认它的状态是已启用(Enabled)。
但问题是,很多人卡在Marketplace这一步:搜索框一直转圈,或者提示网络错误。这多半是IDEA访问JetBrains插件商店的网络链路不通畅导致的。两个替代方案:
第一个替代方案是给IDEA配置插件镜像源。在Preferences -> Plugins界面右上角,有一个设置齿轮图标,点击后选择Manage Plugin Repositories,在这里可以添加镜像仓库地址。添加成功后,再回到Marketplace搜索,响应速度会有明显提升。
第二个替代方案是离线安装。用浏览器访问JetBrains插件商店的网页版,搜索Scala,找到对应IDEA版本的插件包下载到本地。下载的文件是.zip格式,注意不要解压。然后在IDEA的Plugins界面里,点击齿轮图标,选择Install Plugin from Disk...,定位到这个zip文件,确认后即可安装。
离线安装时要注意版本兼容性。每个IDEA版本对应一个内部版本号(比如231、232、233这样的前缀数字),插件页面会标注它支持哪些IDEA版本。如果你下载的插件版本和IDEA版本差得太多,安装时会直接报错,或者装上了但不生效。稳妥的做法是在插件商店页面选择"Versions"标签,找到和你IDEA版本匹配的那一版再下载。
3.3 插件装完但没生效:按这个顺序排查
我见过不少人是这样:插件显示已安装,但新建项目时左侧列表里根本没有Scala选项,或者打开一个.scala文件,代码全部是灰色没有高亮。遇到这种情况,按下面的顺序排查:
先看插件是否真的启用了。Preferences -> Plugins -> Installed,找到Scala,确认右边的勾选框是选中状态,且插件状态不是"Disabled"。有些情况下IDEA会出于兼容性考虑自动禁用插件,需要手动重新启用。
再看IDEA版本和插件版本的匹配度。如果你用的是比较老的IDEA版本,但安装了新版的Scala插件,可能表面显示已安装,实际上没加载成功。反过来,新版本IDEA装老插件也一样。这种问题只有靠升级IDEA或回退插件版本解决。
最后一个很常见的干扰项:你安装的IDEA版本太旧。Scala插件对IDEA版本最低要求不低,如果是2020年以前的IDEA,建议直接升级到最新版本。不要心疼那点升级时间,一个现代IDEA对Scala开发体验的提升非常明显。
4. 创建第一个Scala项目:把环境真正跑起来
4.1 New Project里的Scala选项该怎么选
插件装好、IDEA重启完成后,现在进入正题:新建Scala项目。
点击New Project,左侧类型列表里会出现Scala选项。点进去以后,你通常会看到两个子选项:一个是sbt,一个是IDEA(不同版本叫法可能略有差异,比如"Scala with sbt"和"Scala with IDEA")。
这两种项目类型的区别,用大白话解释是这样的:
| 项目类型 | 构建工具 | 适用场景 |
|---|---|---|
| IDEA项目 | 无外部构建工具,直接依赖IDEA内置编译 | 新手学习、写小练习、不想折腾构建配置 |
| sbt项目 | 使用sbt作为标准构建工具 | 真实项目、需要第三方依赖、后续做复杂工程 |
给新手的建议是:第一个项目选IDEA类型,先把环境跑通、把Scala代码跑起来,建立信心再说。直接上sbt项目,你会在配置文件和依赖下载之间来回折腾,容易消磨学习热情。
接下来是项目里的两个核心配置项:Project SDK和Scala SDK。
Project SDK要选你之前装好的JDK。因为前面说过GUI应用不读~/.zshrc,所以这里IDEA很可能不会自动帮你找到JDK 17,你需要手动点击New...,在弹窗里定位到JDK的安装目录。如果你用的是SDKMAN装的JDK,路径通常在~/.sdkman/candidates/java/17.0.13-tem/这个目录下;如果你用brew装的openjdk@17,路径通常要通过命令行查一下,因为brew的路径很不直观。
然后设置Scala SDK。IDEA会提供两个选择:一个是让你从网上下载某个版本,另一个是让你选择本地已有的Scala路径。如果你没有额外下载过Scala,IDEA的下载功能也能用,但网络不好时容易卡住;如果你之前已经用brew或手动装过Scala,选择Create...或Add...,直接指定Scala的lib目录所在路径即可。
4.2 写一个Hello World并运行
项目创建成功后,默认的目录结构大概是这样的:
my-scala-project ├── src │ ├── main │ │ └── scala │ └── test │ └── scala在src/main/scala目录下,右键新建一个Scala类,文件名取Hello.scala。IDEA会提供几个模板选项,选择Object,然后写入:
object Hello { def main(args: Array[String]): Unit = { println("Hello, Scala!") } }也有人写extends App的版本:
object Hello extends App { println("Hello, Scala!") }两个写法都能跑,区别在于extends App简化了入口方法的定义,更Scala风格。第一次练习用哪种都行。
运行方式极其简单:找到Helloobject,右键,点击Run 'Hello',然后看IDEA底部的控制台窗口。如果你看到输出了Hello, Scala!,恭喜,整个环境已经彻底打通了。
这一步跑通的意义比代码本身大得多。它说明JDK没问题、Scala编译器没问题、IDEA插件没问题、项目配置没问题。后续不管你是学语法还是做项目,都有一个可以信赖的基线环境。
4.3 sbt项目的依赖下载问题,在这里一次性解决
如果你跳过了4.1的建议,直接选了sbt项目,或者以后做真实项目必须用sbt,那依赖下载这个坎早晚要过。sbt项目的核心配置文件是根目录下的build.sbt,它定义了这个项目的名称、版本、Scala版本和第三方依赖。
一个典型的学习项目build.sbt长这样:
ThisBuild / version := "0.1.0" ThisBuild / scalaVersion := "2.13.14" lazy val root = (project in file(".")) .settings( name := "my-scala-project" )IDEA识别到这是一个sbt项目后,会自动执行sbt的导入流程。第一次导入时,sbt会下载它自身的运行时、与当前Scala版本匹配的编译器,以及所有插件和依赖。这一步在没配镜像的情况下会非常痛苦,我见过有人的IDEA在这里转了二十分钟,进度条纹丝不动。
之前第2.3节配置的~/.sbt/repositories镜像就是在这里发挥作用的。如果已经配置好,sbt导入过程会明显变快。还有一种补强手段:我们前面用brew或SDKMAN装的sbt,如果连本地sbt本身都下载依赖困难,可以在~/.sbt/sbtconfig.txt里加上JVM参数,加大内存分配:
-J-Xmx2G -J-XX:+UseG1GC然后重新导入项目。如果IDEA一直显示sbt导入失败,先退出去在命令行手动执行一次sbt,看能不能进入交互界面。命令行能通,说明依赖网络没问题,问题出在IDEA的sbt配置上,可以检查Preferences -> Build Tools -> sbt里的JVM设置和服务目录是否正常。
5. 翻车现场复盘:mac上装Scala最容易踩的四个坑
5.1 终端一切正常,IDEA找不到Scala SDK
这个场景我已经见过太多次了:用户在终端里输入scala -version一切正常,javac也正常,但打开IDEA新建Scala项目时,SDK下拉列表是空的,或者提示"No Scala SDK in module"。
根因在前面已经埋下伏笔:macOS的GUI应用不读取shell的配置文件。你在~/.zshrc里写的JAVA_HOME和PATH,只对终端窗口生效,Finder里启动的IDEA完全感知不到。IDEA本身自带一个JetBrains Runtime,但那是给IDE进程自己用的,不代表它能找到你这个项目需要的JDK和Scala。
解法是:在IDEA的Project Structure里手动指定。点击File -> Project Structure(快捷键Cmd + ;),在Project标签页里设置SDK,在Global Libraries标签页里添加Scala SDK。虽然麻烦一点,但这样最稳定、最不受环境变量问题影响。
还有一个补充方案:如果你希望IDEA能继承终端的那些环境变量,可以在~/.zprofile里配置,或者用launchctl setenv来设置全局环境变量。但我的实际体验是,这些方法要么有安全限制,要么换一个终端工具就失效,不如直接在IDEA里手动指定路径来得干净。
5.2 Apple Silicon机器上的架构错位问题
现在的mac基本都换成了M系列芯片,Apple Silicon和Intel是两套架构,软件也必须匹配对应架构。这个坑在Scala环境搭建中同样存在。
比如你通过brew安装JDK和Scala时,默认装的是arm64版本,这没问题。但如果你下载IDEA时,不小心下载了x86_64架构的Intel版本(有些下载站默认给你的是Intel版),那IDEA会通过Rosetta转译运行,此时它再去匹配JDK时可能会出现异常,或者运行效率下降。
建议的排查和处理方式:下载IDEA时,确认下载的是Apple Silicon版本(下载页面一般会标注"Apple Silicon"或"macOS (Apple Silicon)")。如果已经装了Intel版,想验证当前IDEA运行的架构,可以在终端里执行:
ps aux | grep idea | grep -v grep | awk '{print $11}'看到进程路径能大概判断,但最稳妥的还是直接重装Apple Silicon版。
还有一个相关但更隐蔽的情况:如果你在IDEA里用sbt跑项目,IDEA会启动一个后台sbt进程,这个进程使用的JDK也必须是arm64版本。如果你系统里既有x86的JDK又有arm64的JDK,IDEA可能选中错误的那一个,导致每次编译都报"JVM cannot run on this architecture"之类的错误。检查办法是在IDEA的sbt配置里指定JDK时,确认路径对应的JDK和你本机架构一致。
5.3 .zshrc改了没生效,到底卡在哪
配置了环境变量但终端没反应,这个问题的常见原因有三个:忘了重新加载配置、配置文件写错了、配置了但被后面的配置覆盖了。
改完~/.zshrc后,需要执行source ~/.zshrc或新开一个终端窗口才会生效。这是最基础的一步,但真的有人会漏掉,然后吐槽"改了没用"。
配置文件写错的方式有很多,最常见的是JAVA_HOME路径指向了不存在的目录。mac上有一些遗留下来的Java路径,比如/System/Library/Frameworks/JavaVM.framework/Home,这个路径在很老的系统里出现过,现在已经不可靠了。正确的做法是用/usr/libexec/java_home -V列出所有已安装的JDK,确认你需要的那个版本实际在哪。
还有一个坑:如果你在~/.zshrc里设置了JAVA_HOME,但你又用了alias java=...之类的别名,或者在/etc/paths.d/里添加了其他路径,后面的配置可能会覆盖前面的。排查时用which java看看当前解析到的到底是哪个路径的java,再往前倒推是从哪一层配置来的。
5.4 插件明明装了,项目里就是没反应
这个问题的表现是:Preferences -> Plugins里Scala插件显示已安装,但打开项目后,.scala文件的代码没有高亮,菜单里也没有Run选项。
优先尝试的做法是清缓存重启:File -> Invalidate Caches...,在弹出的对话框里选择Invalidate and Restart。IDEA会清空索引和缓存后自动重启,重启后重新加载项目。这个操作能解决IDEA各式各样的"明明配置了但没反应"问题,就像重启电脑能解决90%日常卡顿一样。
如果清缓存没用,检查项目的.idea目录是否损坏。可以关掉IDEA,删除项目根目录下的.idea文件夹,然后重新打开项目,让IDEA重建配置。注意这个操作会丢失本地的运行配置和窗口布局,但对项目代码不会有影响。
还有一种情况在sbt项目里更常见:外层项目是sbt构建的,IDEA可能在后台还没有成功导入完整项目结构,此时Scala文件没有高亮其实是假象,等sbt导入进度条跑完、External Libraries里出现了Scala相关的jar包后,一切就恢复正常了。判断方法是在IDEA右侧找到sbt工具窗口,看看有没有导入错误。
最后讲一下我现在每次在mac上配Scala环境的固定顺序,算是一点个人经验。我用SDKMAN装JDK 17,用~/.sbt/repositories配好镜像,去官网下对应芯片架构的IDEA,装好插件后直接建本地Scala SDK的练习项目。整个过程走下来,最花时间的不是安装本身,而是依赖下载和版本匹配。换句话说,Scala环境安装这件事,90%的坑都集中在两处:终端环境与GUI应用的环境变量不一致、官方源的网络访问不稳定。抓住这两条主线去排查,剩下的问题基本都能迎刃而解。这套流程我用过不止一次,在Intel Mac和Apple Silicon上都验证过,希望也能帮你少踩几个坑。