[SCALA] 스칼라 파일에서 jar 파일 만들기
SCALA스칼라 파일에서 jar 파일 만들기
나는 스칼라에 새로 온 사람과 자바를 모른다. 나는 간단한 스칼라 파일에서 jar 파일을 만들려고합니다. 내 HelloWorld.scala을하며,이 례 HelloWorld.jar를 생성합니다.
MANIFEST.MF :
Main-Class: HelloWorld
콘솔에서 나는 실행 :
fsc HelloWorld.scala
jar -cvfm HelloWorld.jar Manifest.mf HelloWorld\$.class HelloWorld.class
java -jar HelloWorld.jar
=> "Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld/jar"
java -cp HelloWorld.jar HelloWorld
=> Exception in thread "main" java.lang.NoClassDefFoundError: scala/ScalaObject
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:675)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
at java.net.URLClassLoader.access$100(URLClassLoader.java:56)
at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:316)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:280)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:374)
at hoppity.main(HelloWorld.scala)
해결법
-
==============================
1.샘플 디렉토리 구조 :
샘플 디렉토리 구조 :
X:\scala\bin X:\scala\build.bat X:\scala\MANIFEST.MF X:\scala\src X:\scala\src\foo X:\scala\src\foo\HelloWorld.scala
HelloWorld.scala :
//file: foo/HelloWorld.scala package foo { object HelloWorld { def main(args: Array[String]) { println("Hello, world!") } } }
MANIFEST.MF :
Main-Class: foo.HelloWorld Class-Path: scala-library.jar
경우 build.bat :
@ECHO OFF IF EXIST hellow.jar DEL hellow.jar IF NOT EXIST scala-library.jar COPY %SCALA_HOME%\lib\scala-library.jar . CALL scalac -sourcepath src -d bin src\foo\HelloWorld.scala CD bin jar -cfm ..\hellow.jar ..\MANIFEST.MF *.* CD .. java -jar hellow.jar
성공적으로 -jar 스위치를 사용하려면, 당신은 META-INF / MANIFEST.MF 파일에 두 개의 항목이 필요합니다 주요 클래스; 종속성에 대한 상대 URL. 문서 참고 사항 :
(참고 : JAR 파일은 대부분의 우편 응용 프로그램과 함께 검사 할 수 있으며, 아마 방치 배치 스크립트에서 디렉토리 이름에 공백을 처리, 스칼라 코드 주자 버전 2.7.4.final합니다.)
완성도를 들어, 해당 bash는 스크립트 :
#!/bin/bash if [ ! $SCALA_HOME ] then echo ERROR: set a SCALA_HOME environment variable exit fi if [ ! -f scala-library.jar ] then cp $SCALA_HOME/lib/scala-library.jar . fi scalac -sourcepath src -d bin src/foo/HelloWorld.scala cd bin jar -cfm ../hellow.jar ../MANIFEST.MF * cd .. java -jar hellow.jar
-
==============================
2.스칼라 스크립트는 스칼라가 설치 될 도서관 필요하기 때문에, 당신은 당신의 JAR와 함께 스칼라 런타임을 포함해야합니다.
스칼라 스크립트는 스칼라가 설치 될 도서관 필요하기 때문에, 당신은 당신의 JAR와 함께 스칼라 런타임을 포함해야합니다.
이 같은 항아리 항아리로이 작업을 수행하기위한 많은 전략은,하지만 궁극적으로 문제가 당신이있는 거 보는 당신이 시작했습니다 자바 프로세스가 스칼라 JAR 파일을 찾을 수 있다는 것입니다.
간단한 독립형 스크립트, 난 그렇지 않으면 종속성 관리 도구보고 시작하거나 JDK에 스칼라를 설치하도록 요구해야한다, 항아리 항아리를 사용하는 것이 좋습니다 것입니다.
-
==============================
3.나는 그것이 정말 사용하기 간단하고, 조립 SBT를 사용하여 끝났다. 나는 하나의 라이너 (변경해야 할 수도 버전을 참고)와 함께 프로젝트의 루트에있는 프로젝트 / 디렉토리에 assembly.sbt라는 파일을 추가했습니다.
나는 그것이 정말 사용하기 간단하고, 조립 SBT를 사용하여 끝났다. 나는 하나의 라이너 (변경해야 할 수도 버전을 참고)와 함께 프로젝트의 루트에있는 프로젝트 / 디렉토리에 assembly.sbt라는 파일을 추가했습니다.
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.11.2")
그럼 그냥 SBT의 조립 작업을 실행 :
> assembly
아니면 그냥 프로젝트의 루트 디렉토리에 '조립 SBT'
$ sbt assembly
그것은 먼저 테스트를 실행 한 후 대상 / 디렉토리에 새 항아리를 생성합니다 (내 build.sbt 이미 내 모든 종속성을 나열 주어진).
내 경우에는, 난 그냥 그 .jar 파일의 실행을 확장을 제거하기 위해 이름을 변경하고 그것을 제공 할 준비가되어 있습니다!
당신이 명령 줄 도구를하고있는 경우에도, 사람 페이지를 (심지어 당신을 위해 호출기로 파이프되지 않은 적절한 맨없이 또는 여러 페이지 일반 텍스트 문서와 스크립트를 싫어)을 추가하는 것을 잊지 마세요.
-
==============================
4.또한 받는다는과 받는다는 - 스칼라 - 플러그인을 사용할 수 있습니다. 당신이 받는다는 설정하면, 당신은 단지 MVN 패키지를 할 수 있으며, 그것은 당신을 위해 단지를 만들 것입니다.
또한 받는다는과 받는다는 - 스칼라 - 플러그인을 사용할 수 있습니다. 당신이 받는다는 설정하면, 당신은 단지 MVN 패키지를 할 수 있으며, 그것은 당신을 위해 단지를 만들 것입니다.
-
==============================
5.나는 MyDowell의 방법을 재현 해 보았습니다. 마지막으로 나는 그것이 작동되도록 할 수있다. 그러나 나는 올바른 비트가 너무 초보자 복잡하지만 대답 (특정 디렉토리 구조에서 불필요하게 복잡) 것을 찾을 수 있습니다.
나는 MyDowell의 방법을 재현 해 보았습니다. 마지막으로 나는 그것이 작동되도록 할 수있다. 그러나 나는 올바른 비트가 너무 초보자 복잡하지만 대답 (특정 디렉토리 구조에서 불필요하게 복잡) 것을 찾을 수 있습니다.
나는 매우 단순한 수단이 결과를 재현 할 수 있습니다. 세 개의 파일이 들어있는 하나의 디렉토리가 시작하려면 :
helloworld.scala MANIFEST.MF scala-library.jar
helloworld.scala
object HelloWorld { def main(args: Array[String]) { println("Hello, world!") } }
MANIFEST.MF :
Main-Class: HelloWorld Class-Path: scala-library.jar
첫 번째 컴파일 helloworld.scala :
scalac helloworld.scala
다음 항아리를 만들 :
\progra~1\java\jdk18~1.0_4\bin\jar -cfm helloworld.jar MANIFEST.MF .
지금 당신은 그것을 실행할 수 있습니다 :
java -jar helloworld.jar
원래는 작동하지 않았다 때문에 나는이 간단한 해결책을 발견. 내가 줄 바꿈과의 긴밀한 MANIFEST.MF에서 두 번째 줄을하지 않으면,이 라인은 무시됩니다 나중에 내가 잘못 때문이 아니라 사소한 오류입니다 때문이 아니라 사실을 발견했다. 이 알아 나에게 시간을했고 나는이 아주 간단한 해결책을 찾는 과정에서, 이전에 다른 모든 것을 시도했다.
-
==============================
6.그 이유의를 작성하지 않을 방법이 아니라 단지 (우분투 리눅스 명령 줄을 통해) 내 경우에는 근무 솔루션을 보여줄 것 :
그 이유의를 작성하지 않을 방법이 아니라 단지 (우분투 리눅스 명령 줄을 통해) 내 경우에는 근무 솔루션을 보여줄 것 :
1)
mkdir scala-jar-example cd scala-jar-example
2)
nano Hello.scala object Hello extends App { println("Hello, world") }
3)
nano build.sbt import AssemblyKeys._ assemblySettings name := "MyProject" version := "1.0" scalaVersion := "2.11.0"
3)
mkdir project cd project nano plugins.sbt addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.9.1")
4)
cd ../ sbt assembly
5)
java -jar target/target/scala-2.11/MyProject-assembly-1.0.jar >> Hello, world
-
==============================
7.나는 자동 매니페스트 생성 등 일부 정보를 추가 bash는 스크립트를 수정했습니다.
나는 자동 매니페스트 생성 등 일부 정보를 추가 bash는 스크립트를 수정했습니다.
이 스크립트는 기본 개체가가에있는 파일 (대소 문자 구분)과 동일한라는 것으로 가정합니다. 또한, 하나의 현재 디렉토리 이름은 메인 오브젝트 이름과 동일해야하며 메인 오브젝트 이름은 커맨드 라인 파라미터로서 제공한다. 프로젝트의 루트 디렉토리에서이 스크립트를 실행합니다. 필요에 따라 상단에있는 변수를 수정합니다.
스크립트가 빈과의 dist 폴더를 생성하고 빈에있는 기존 내용을 삭제된다는 점에 유의하십시오.
#!/bin/bash SC_DIST_PATH=dist SC_SRC_PATH=src SC_BIN_PATH=bin SC_INCLUDE_LIB_JAR=scala-library.jar SC_MANIFEST_PATH=MANIFEST.MF SC_STARTING_PATH=$(pwd) if [[ ! $SCALA_HOME ]] ; then echo "ERROR: set a SCALA_HOME environment variable" exit 1 fi if [[ ! -f $SCALA_HOME/lib/$SC_INCLUDE_LIB_JAR ]] ; then echo "ERROR: Cannot find Scala Libraries!" exit 1 fi if [[ -z "$1" ]] ; then SC_APP=$(basename $SC_STARTING_PATH) else SC_APP=$1 fi [[ ! -d $SC_DIST_PATH ]] && mkdir $SC_DIST_PATH if [[ ! -d $SC_BIN_PATH ]] ; then mkdir "$SC_BIN_PATH" else rm -r "$SC_BIN_PATH" if [[ -d $SC_BIN_PATH ]] ; then echo "ERROR: Cannot remove temp compile directory: $SC_BIN_PATH" exit 1 fi mkdir "$SC_BIN_PATH" fi if [[ ! -d $SC_SRC_PATH ]] || [[ ! -d $SC_DIST_PATH ]] || [[ ! -d $SC_BIN_PATH ]] ; then echo "ERROR: Directory not found!: $SC_SRC_PATH or $SC_DIST_PATH or $SC_BIN_PATH" exit 1 fi if [[ ! -f $SC_DIST_PATH/$SC_INCLUDE_LIB_JAR ]] ; then cp "$SCALA_HOME/lib/$SC_INCLUDE_LIB_JAR" "$SC_DIST_PATH" fi SCALA_MAIN=$(find ./$SC_SRC_PATH -name "$SC_APP.scala") COMPILE_STATUS=$? SCALA_MAIN_COUNT=$(echo "$SCALA_MAIN" | wc -l) if [[ $SCALA_MAIN_COUNT != "1" ]] || [[ ! $COMPILE_STATUS == 0 ]] ; then echo "Main source file not found or too many exist!: $SC_APP.scala" exit 1 fi if [[ -f $SC_DIST_PATH/$SC_APP.jar ]] ; then rm "$SC_DIST_PATH/$SC_APP.jar" if [[ -f $SC_DIST_PATH/$SC_APP.jar ]] ; then echo "Unable to remove existing distribution!: $SC_DIST_PATH/$SC_APP.jar" exit 1 fi fi if [[ ! -f $SC_MANIFEST_PATH ]] ; then LEN_BASE=$(echo $(( $(echo "./$SC_SRC_PATH" |wc -c) - 0 ))) SC_MAIN_CLASS=$(echo $SCALA_MAIN |cut --complement -c1-$LEN_BASE) SC_MAIN_CLASS=${SC_MAIN_CLASS%%.*} SC_MAIN_CLASS=$(echo $SC_MAIN_CLASS |awk '{gsub( "/", "'"."'"); print}') echo $(echo "Main-Class: "$SC_MAIN_CLASS) > $SC_MANIFEST_PATH echo $(echo "Class-Path: "$SC_INCLUDE_LIB_JAR) >> $SC_MANIFEST_PATH fi scalac -sourcepath $SC_SRC_PATH -d $SC_BIN_PATH $SCALA_MAIN COMPILE_STATUS=$? if [[ $COMPILE_STATUS != "0" ]] ; then echo "Compile Failed!" exit 1 fi cd "$SC_BIN_PATH" jar -cfm ../$SC_DIST_PATH/$SC_APP.jar ../$SC_MANIFEST_PATH * COMPILE_STATUS=$? cd "$SC_STARTING_PATH" if [[ $COMPILE_STATUS != "0" ]] || [[ ! -f $SC_DIST_PATH/$SC_APP.jar ]] ; then echo "JAR Build Failed!" exit 1 fi echo " " echo "BUILD COMPLETE!... TO LAUNCH: java -jar $SC_DIST_PATH/$SC_APP.jar" echo " "
-
==============================
8.(이것은 초기 질문 위의 문제가 아니다 있지만) 유사한 문제가 발생할 수 있습니다 한가지는 Java VM이 주요 방법은 무효 반환 요구 보인다는 것이다. 스칼라에서 우리는 같은 (메인의 정의에 = -sign을 관찰)을 쓸 수 있습니다 :
(이것은 초기 질문 위의 문제가 아니다 있지만) 유사한 문제가 발생할 수 있습니다 한가지는 Java VM이 주요 방법은 무효 반환 요구 보인다는 것이다. 스칼라에서 우리는 같은 (메인의 정의에 = -sign을 관찰)을 쓸 수 있습니다 :
object MainProgram { def main(args: Array[String]) = { new GUI(args) } }
주요 실제로 GUI 객체를 반환 경우 (즉, 그것은 무효 아니다),하지만 우리는 스칼라 명령을 사용하여 시작할 때 프로그램이 잘 실행됩니다.
우리는 메인 클래스로 메인 프로 그램과 항아리 파일에이 코드를 패키지 경우 Java VM이 우리의 주요의 반환 형식이 무효가 아니므로 아무 주요 기능은 없다 불평한다 (I은 다소 이상이 불만을 찾을 이후 반환 형식은 서명의 일부)이 아니다.
우리가 명시 적으로 단위로 선언 된 경우, 우리는 우리가 주요의 헤더에 = -sign에서 제외하면 아무런 문제가, 또는 것입니다.
-
==============================
9.당신은 SBT 기능을 사용하지 않으려면 나는 메이크의 사용을 권장합니다.
당신은 SBT 기능을 사용하지 않으려면 나는 메이크의 사용을 권장합니다.
여기에 foo는 패키지가 완성도 foo.bar.myApp로 대체하는 예이다.
메이크
NAME=HelloWorld JARNAME=helloworld PACKAGE=foo.bar.myApp PATHPACK=$(subst .,/,$(PACKAGE)) .DUMMY: default default: $(NAME) .DUMMY: help help: @echo "make [$(NAME)]" @echo "make [jar|runJar]" @echo "make [clean|distClean|cleanAllJars|cleanScalaJar|cleanAppJar]" .PRECIOUS: bin/$(PATHPACK)/%.class bin/$(PATHPACK)/%.class: src/$(PATHPACK)/%.scala scalac -sourcepath src -d bin $< scala-library.jar: cp $(SCALA_HOME)/lib/scala-library.jar . .DUMMY: runjar runJar: jar java -jar $(JARNAME).jar .DUMMY: jar jar: $(JARNAME).jar MANIFEST.MF: @echo "Main-Class: $(PACKAGE).$(NAME)" > $@ @echo "Class-Path: scala-library.jar" >> $@ $(JARNAME).jar: scala-library.jar bin/$(PATHPACK)/$(NAME).class \ MANIFEST.MF (cd bin && jar -cfm ../$(JARNAME).jar ../MANIFEST.MF *) %: bin/$(PATHPACK)/%.class scala -cp bin $(PACKAGE).$@ .DUMMY: clean clean: rm -R -f bin/* MANIFEST.MF cleanAppJar: rm -f $(JARNAME).jar cleanScalaJar: rm -f scala-library.jar cleanAllJars: cleanAppJar cleanScalaJar distClean cleanDist: clean cleanAllJars
from https://stackoverflow.com/questions/809138/creating-a-jar-file-from-a-scala-file by cc-by-sa and MIT license
'SCALA' 카테고리의 다른 글
[SCALA] 스칼라 함수를 정의의이 세 가지 방법의 차이 (0) | 2019.11.14 |
---|---|
[SCALA] 포스트 그레스 표에 Dataframes UPSERT 불꽃 (0) | 2019.11.14 |
[SCALA] 자원 스칼라 폴더에서 어떻게 파일을 읽을? (0) | 2019.11.14 |
[SCALA] Scalaz 상태 모나드 예 (0) | 2019.11.14 |
[SCALA] 스칼라 기능적 대하여 반응성 프로그래밍 [폐쇄] (0) | 2019.11.14 |