Alert

์ด ๊ธ€์€ Claude Code์˜ ๋„์›€์„ ๋ฐ›์•„ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค

TL;DR

  • JAR์€ Java์˜ ํŒจํ‚ค์ง• ํฌ๋งท์ด๊ณ , DE ๋„๊ตฌ(Flink, Spark, Kafka ๋“ฑ)๊ฐ€ JVM ๊ธฐ๋ฐ˜์ด๋ผ ์ž์ฃผ ๋งˆ์ฃผ์นœ๋‹ค
  • Fat JAR์€ ์˜์กด์„ฑ์„ ๋ชฝ๋•… ๋‹ด์€ ๋‹จ์ผ ์‹คํ–‰ ํŒŒ์ผ, Thin JAR์€ ์ž๊ธฐ ์ฝ”๋“œ๋งŒ ๋‹ด์€ ๊ฐ€๋ฒผ์šด ํŒŒ์ผ
  • Shading์€ Fat JAR์„ ๋งŒ๋“ค ๋•Œ ํŒจํ‚ค์ง€ ์ถฉ๋Œ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ๊ฒฝ๋กœ๋ฅผ ์žฌ๋ฐฐ์น˜ํ•˜๋Š” ๊ธฐ์ˆ 

1. JAR์ด ๋ญ”๋ฐ, ์™œ DE์—์„œ ์ž๊พธ ๋‚˜์™€?

JAR = Java Archive

JAR์€ Java ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผํ•œ .class ํŒŒ์ผ๊ณผ ์„ค์ • ํŒŒ์ผ๋“ค์„ ํ•˜๋‚˜๋กœ ๋ฌถ์€ ์••์ถ• ํŒŒ์ผ์ด๋‹ค. ๋ณธ์งˆ์ ์œผ๋กœ zip ํŒŒ์ผ๊ณผ ๊ฐ™๋‹ค.

# JAR ๋‚ด๋ถ€ ๊ตฌ์กฐ ํ™•์ธ (์‹ค์ œ๋กœ zip์ด๋‹ค)
unzip -l some-library.jar
jar tf some-library.jar

Python์—์„œ .whl์ด ํŒจํ‚ค์ง€ ๋ฐฐํฌ ๋‹จ์œ„์ธ ๊ฒƒ์ฒ˜๋Ÿผ, Java ์ƒํƒœ๊ณ„์—์„œ๋Š” .jar์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฐฐํฌ ๋‹จ์œ„๋‹ค.

์™œ DE ๋„๊ตฌ๋“ค์ด ์ „๋ถ€ Java(JVM) ๊ธฐ๋ฐ˜์ธ๊ฐ€?

๋Œ€๋ถ€๋ถ„์˜ ๋ถ„์‚ฐ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๋„๊ตฌ๋Š” 2000๋…„๋Œ€ ํ›„๋ฐ˜~2010๋…„๋Œ€ ์ดˆ๋ฐ˜์— ํƒ„์ƒํ–ˆ๋‹ค. ์ด ์‹œ๊ธฐ์— ๋Œ€๊ทœ๋ชจ ๋ถ„์‚ฐ ์‹œ์Šคํ…œ์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ํ˜„์‹ค์ ์ธ ์„ ํƒ์ง€๊ฐ€ Java/JVM์ด์—ˆ๋‹ค.

  • Hadoop(2006) ์ด ์‹œ์ž‘์ ์ด๋‹ค. Google์˜ MapReduce ๋…ผ๋ฌธ์„ Java๋กœ ๊ตฌํ˜„ํ•œ ๊ฒƒ์ด Hadoop์ด๊ณ , ์ดํ›„ ๋Œ€๋ถ€๋ถ„์˜ ๋น…๋ฐ์ดํ„ฐ ๋„๊ตฌ๊ฐ€ Hadoop ์ƒํƒœ๊ณ„ ์œ„์— ๋งŒ๋“ค์–ด์กŒ๋‹ค
  • JVM์˜ ๊ฐ•์  โ€” ํฌ๋กœ์Šค ํ”Œ๋žซํผ(โ€œWrite Once, Run Anywhereโ€), ๊ฒ€์ฆ๋œ GC์™€ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ, ํ’๋ถ€ํ•œ ๋„คํŠธ์›Œํฌ/์ง๋ ฌํ™” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋ถ„์‚ฐ ์‹œ์Šคํ…œ ๊ฐœ๋ฐœ์— ์ ํ•ฉํ–ˆ๋‹ค
  • ์ƒํƒœ๊ณ„ ์—ฐ์‡„ ํšจ๊ณผ โ€” Hadoop์ด Java๋‹ˆ๊นŒ ๊ทธ ์œ„์— ๋งŒ๋“œ๋Š” Hive, HBase๋„ Java, ๊ทธ ๋‹ค์Œ ์„ธ๋Œ€์ธ Spark(Scala/JVM), Kafka(Java), Flink(Java)๋„ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ JVM์„ ์„ ํƒํ–ˆ๋‹ค
๋„๊ตฌ์–ธ์–ด์‹œ์ž‘ ์—ฐ๋„๋น„๊ณ 
HadoopJava2006Google MapReduce์˜ ์˜คํ”ˆ์†Œ์Šค ๊ตฌํ˜„
HiveJava2010Hadoop ์œ„์˜ SQL ์—”์ง„
KafkaJava/Scala2011LinkedIn์—์„œ ๊ฐœ๋ฐœ
SparkScala(JVM)2014Hadoop MapReduce์˜ ๋Œ€์•ˆ
FlinkJava2014์ŠคํŠธ๋ฆผ ์ฒ˜๋ฆฌ ์ค‘์‹ฌ
AirflowPython2014์›Œํฌํ”Œ๋กœ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ดํ„ฐ (JVM ์•„๋‹˜)

Python์œผ๋กœ ์“ฐ๋Š”๋ฐ ์™œ JAR์„ ์•Œ์•„์•ผ ํ• ๊นŒ?

PySpark, PyFlink ๊ฐ™์€ Python API๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ JVM ํ”„๋กœ์„ธ์Šค๋ฅผ ๋„์›Œ์„œ ๋™์ž‘ํ•œ๋‹ค. Python์€ ๋“œ๋ผ์ด๋ฒ„ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ผ ๋ฟ, ์‹ค์ œ ๋ถ„์‚ฐ ์ฒ˜๋ฆฌ๋Š” JVM์ด ํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ์ปค๋„ฅํ„ฐ ์„ค์น˜, ์˜์กด์„ฑ ์ถฉ๋Œ, ํด๋ž˜์ŠคํŒจ์Šค ๋ฌธ์ œ ๋“ฑ JVM ์ชฝ ์ด์Šˆ๋ฅผ ํ”ผํ•  ์ˆ˜ ์—†๋‹ค.

DE์—์„œ JAR์„ ์ง์ ‘ ๋‹ค๋ฃจ๋Š” ์ƒํ™ฉ๋“ค
  • ์ปค๋„ฅํ„ฐ ์„ค์น˜ โ€” Flink SQL์—์„œ Kafka ์†Œ์Šค๋ฅผ ์“ฐ๋ ค๋ฉด flink-sql-connector-kafka-*.jar์„ lib/์— ๋„ฃ์–ด์•ผ ํ•œ๋‹ค
  • Spark job ์ œ์ถœ โ€” spark-submit app.jar๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ JAR์„ ํด๋Ÿฌ์Šคํ„ฐ์— ์ „๋‹ฌํ•œ๋‹ค
  • JDBC ๋“œ๋ผ์ด๋ฒ„ โ€” Airflow๋‚˜ Spark์—์„œ DB์— ์—ฐ๊ฒฐํ•  ๋•Œ ๋“œ๋ผ์ด๋ฒ„ JAR์„ ํด๋ž˜์ŠคํŒจ์Šค์— ์ถ”๊ฐ€ํ•œ๋‹ค
  • ์˜์กด์„ฑ ์ถฉ๋Œ ํ•ด๊ฒฐ โ€” ์„œ๋กœ ๋‹ค๋ฅธ ๋ฒ„์ „์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ถฉ๋Œํ•  ๋•Œ Fat/Thin JAR๊ณผ Shading ๊ฐœ๋…์ด ํ•„์š”ํ•˜๋‹ค

2. ์šฉ์–ด ์ •์˜

Fat JAR (Uber JAR)
  • ๋ชจ๋“ˆ ์ž์ฒด ์ฝ”๋“œ + ๋ชจ๋“  ์˜์กด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ•˜๋‚˜์˜ JAR๋กœ ํ•ฉ์นœ ํŒŒ์ผ
  • โ€œFatโ€์ด๋ผ๋Š” ์ด๋ฆ„์€ ์˜์กด ์ฝ”๋“œ๊นŒ์ง€ ์ „๋ถ€ ํฌํ•จํ•ด์„œ ํŒŒ์ผ ๋ฉ์น˜๊ฐ€ ํฌ๋‹ค๋Š” ๋น„์œ ์—์„œ ์™”๋‹ค
  • Uber๋Š” ๋…์ผ์–ด๋กœ โ€œ~์œ„์˜, ์ดˆ์›”ํ•œโ€์ด๋ผ๋Š” ๋œป์œผ๋กœ, ์ผ๋ฐ˜ JAR์„ ๋„˜์–ด์„ ๋‹ค๋Š” ์˜๋ฏธ
Thin JAR (Slim JAR)
  • ๋ชจ๋“ˆ ์ž์ฒด ์ฝ”๋“œ๋งŒ ๋‹ด๊ณ , ์˜์กด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๋Ÿฐํƒ€์ž„์— ๋ณ„๋„ ์ œ๊ณต๋œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋Š” JAR
  • MANIFEST.MF์˜ Class-Path ํ•ญ๋ชฉ์ด๋‚˜ ์™ธ๋ถ€ lib ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ํ†ตํ•ด ์˜์กด์„ฑ์„ ์ฐธ์กฐํ•œ๋‹ค
Shading (Relocating)
  • Fat JAR์„ ๋งŒ๋“ค๋ฉด์„œ ๋‚ด๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ํŒจํ‚ค์ง€ ๊ฒฝ๋กœ๋ฅผ ์žฌ๋ฐฐ์น˜(relocate) ํ•˜๋Š” ๊ธฐ์ˆ 
  • ์˜ˆ: com.google.guava โ†’ my.shaded.com.google.guava
  • ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์„œ๋กœ ๋‹ค๋ฅธ ๋ฒ„์ „์ด ํด๋ž˜์ŠคํŒจ์Šค์— ๊ณต์กดํ•  ๋•Œ ์ƒ๊ธฐ๋Š” ์ถฉ๋Œ์„ ๋ฐฉ์ง€ํ•œ๋‹ค

3. Fat JAR vs Thin JAR ๋น„๊ต

๊ตฌ๋ถ„Fat JARThin JAR
ํฌํ•จ ๋‚ด์šฉ๋ชจ๋“ˆ ์ฝ”๋“œ + ๋ชจ๋“  ์˜์กด JAR๋ชจ๋“ˆ ์ฝ”๋“œ๋งŒ
ํŒŒ์ผ ํฌ๊ธฐํผ (์ˆ˜์‹ญ~์ˆ˜๋ฐฑ MB)์ž‘์Œ (์ˆ˜ KB~์ˆ˜ MB)
๋ฐฐํฌ ํŽธ์˜์„ฑํŒŒ์ผ ํ•˜๋‚˜๋งŒ ์ „๋‹ฌํ•˜๋ฉด ๋์˜์กด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ•จ๊ป˜ ๋ฐฐํฌํ•ด์•ผ ํ•จ
์˜์กด์„ฑ ๊ด€๋ฆฌJAR ๋‚ด๋ถ€์— ๊ณ ์ •๋จ์™ธ๋ถ€์—์„œ ๋ฒ„์ „์„ ์ง์ ‘ ์ œ์–ด ๊ฐ€๋Šฅ
์ถฉ๋Œ ์œ„ํ—˜์—ฌ๋Ÿฌ Fat JAR์ด ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ค‘๋ณต ํฌํ•จํ•  ์ˆ˜ ์žˆ์Œํ•˜๋‚˜์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ณต์œ ํ•˜๋ฏ€๋กœ ์ค‘๋ณต ์—†์Œ
์‹คํŒจ ๋ชจ๋“œ๋ฒ„์ „ ์ถฉ๋Œ ์‹œ NoSuchMethodError์˜์กด ๋ˆ„๋ฝ ์‹œ ClassNotFoundException

์–ธ์ œ ๋ญ˜ ์“ธ๊นŒ?

  • Fat JAR โ†’ CLI ๋„๊ตฌ, Lambda ๋ฐฐํฌ, Flink/Spark job ์ œ์ถœ์ฒ˜๋Ÿผ ๋‹จ์ผ ํŒŒ์ผ ์‹คํ–‰์ด ํ•„์š”ํ•  ๋•Œ
  • Thin JAR โ†’ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฐฐํฌ, ์˜์กด ๋ฒ„์ „์„ ์†Œ๋น„์ž๊ฐ€ ์ง์ ‘ ๊ฒฐ์ •ํ•ด์•ผ ํ•  ๋•Œ

4. Shading์ด ํ•„์š”ํ•œ ์ด์œ 

JVM์€ ๊ฐ™์€ FQCN(Fully Qualified Class Name)์„ ๊ฐ€์ง„ ํด๋ž˜์Šค๊ฐ€ ํด๋ž˜์ŠคํŒจ์Šค์— ๋‘ ๊ฐœ ์ด์ƒ ์žˆ์œผ๋ฉด ๋จผ์ € ๋ฐœ๊ฒฌ๋œ ๊ฒƒ๋งŒ ๋กœ๋“œํ•œ๋‹ค. ์ด๊ฒƒ์ด JAR Hell์˜ ํ•ต์‹ฌ์ด๋‹ค.

์ „ํ˜•์ ์ธ ์ถฉ๋Œ ์‹œ๋‚˜๋ฆฌ์˜ค
๋‚ด ํ”„๋กœ์ ํŠธ โ†’ guava 31
    โ””โ”€โ”€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ A โ†’ guava 27 (Fat JAR์— ํฌํ•จ)

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ A์˜ Fat JAR์— guava 27์ด ๋“ค์–ด ์žˆ๋Š”๋ฐ, ๋‚ด ํ”„๋กœ์ ํŠธ๋Š” guava 31์„ ์“ด๋‹ค. ํด๋ž˜์ŠคํŒจ์Šค์— guava๊ฐ€ ๋‘ ๋ฒŒ ์˜ฌ๋ผ๊ฐ€๋ฉด์„œ NoSuchMethodError๊ฐ€ ํ„ฐ์ง„๋‹ค.

Shading์œผ๋กœ ํ•ด๊ฒฐ

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ A๋ฅผ ๋นŒ๋“œํ•  ๋•Œ guava๋ฅผ shading ์ฒ˜๋ฆฌํ•˜๋ฉด ๋‚ด๋ถ€์ ์œผ๋กœ com.google.common โ†’ a.shaded.com.google.common์œผ๋กœ ๋ฐ”๋€๋‹ค. ๋‘ guava๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅธ ํŒจํ‚ค์ง€ ๊ฒฝ๋กœ๋ฅผ ๊ฐ–๊ฒŒ ๋˜๋ฏ€๋กœ ์ถฉ๋Œ์ด ์‚ฌ๋ผ์ง„๋‹ค.


5. ๋นŒ๋“œ ๋„๊ตฌ๋ณ„ Fat JAR ๋งŒ๋“ค๊ธฐ

Maven โ€” maven-shade-plugin
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <version>3.6.0</version>
  <executions>
    <execution>
      <phase>package</phase>
      <goals><goal>shade</goal></goals>
      <configuration>
        <relocations>
          <relocation>
            <pattern>com.google.common</pattern>
            <shadedPattern>my.shaded.com.google.common</shadedPattern>
          </relocation>
        </relocations>
      </configuration>
    </execution>
  </executions>
</plugin>
mvn package
# target/my-app-1.0-SNAPSHOT.jar  โ† shading ์ ์šฉ๋œ Fat JAR
Maven โ€” maven-assembly-plugin

shading ์—†์ด ๋‹จ์ˆœํžˆ ์˜์กด์„ฑ์„ ํ•ฉ์น˜๊ธฐ๋งŒ ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <version>3.7.1</version>
  <configuration>
    <descriptorRefs>
      <descriptorRef>jar-with-dependencies</descriptorRef>
    </descriptorRefs>
    <archive>
      <manifest>
        <mainClass>com.example.Main</mainClass>
      </manifest>
    </archive>
  </configuration>
</plugin>
Gradle โ€” Shadow Plugin
plugins {
    id 'com.github.johnrengelman.shadow' version '8.1.1'
}
 
shadowJar {
    relocate 'com.google.common', 'my.shaded.com.google.common'
}
./gradlew shadowJar
# build/libs/my-app-1.0-all.jar

shade vs shadow

Maven์—์„œ๋Š” shade, Gradle์—์„œ๋Š” shadow๋ผ๋Š” ์ด๋ฆ„์„ ์“ฐ์ง€๋งŒ ํ•˜๋Š” ์ผ์€ ๋™์ผํ•˜๋‹ค. ์˜์กด์„ฑ์„ Fat JAR๋กœ ํ•ฉ์น˜๋ฉด์„œ ์„ ํƒ์ ์œผ๋กœ ํŒจํ‚ค์ง€ ๊ฒฝ๋กœ๋ฅผ relocate ํ•œ๋‹ค.


6. Spring Boot์˜ Fat JAR

Spring Boot๋Š” Java์˜ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ”„๋ ˆ์ž„์›Œํฌ๋‹ค. Python์˜ Django/FastAPI, Node.js์˜ Express ๊ฐ™์€ ํฌ์ง€์…˜์œผ๋กœ, Java ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์—์„œ ์‚ฌ์‹ค์ƒ ํ‘œ์ค€์ด๋‹ค.

Spring Boot๋Š” ์ž์ฒด์ ์ธ Fat JAR ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์ผ๋ฐ˜์ ์ธ Uber JAR๊ณผ๋Š” ๋‹ค๋ฅธ ๋ฐฉ์‹์ด๋‹ค.

๊ตฌ์กฐ ์ฐจ์ด
# ์ผ๋ฐ˜ Uber JAR โ€” ๋ชจ๋“  .class๋ฅผ ํ’€์–ด์„œ ํ•ฉ์นจ
my-app.jar
โ”œโ”€โ”€ com/example/Main.class
โ”œโ”€โ”€ com/google/common/...
โ””โ”€โ”€ org/apache/...

# Spring Boot Fat JAR โ€” ์˜์กด JAR์„ ๊ทธ๋Œ€๋กœ ๋‚ด์žฅ
my-app.jar
โ”œโ”€โ”€ BOOT-INF/
โ”‚   โ”œโ”€โ”€ classes/        โ† ๋‚ด ์ฝ”๋“œ
โ”‚   โ””โ”€โ”€ lib/            โ† ์˜์กด JAR ํŒŒ์ผ๋“ค (์›๋ณธ ๊ทธ๋Œ€๋กœ)
โ”œโ”€โ”€ META-INF/
โ””โ”€โ”€ org/springframework/boot/loader/  โ† ์ปค์Šคํ…€ ํด๋ž˜์Šค๋กœ๋”
  • Spring Boot๋Š” ์˜์กด JAR์„ ํ’€์ง€ ์•Š๊ณ  ์›๋ณธ JAR ๊ทธ๋Œ€๋กœ ๋‚ด์žฅํ•œ๋‹ค
  • spring-boot-loader๋ผ๋Š” ์ปค์Šคํ…€ ํด๋ž˜์Šค๋กœ๋”๊ฐ€ BOOT-INF/lib/ ์•ˆ์˜ JAR์„ ์ฝ๋Š”๋‹ค
  • ์ด ๋ฐฉ์‹ ๋•๋ถ„์— shading ์—†์ด๋„ ํด๋ž˜์Šค ์ถฉ๋Œ ๋ฌธ์ œ๊ฐ€ ์ค„์–ด๋“ ๋‹ค
# Spring Boot Fat JAR ์‹คํ–‰
java -jar my-app.jar
 
# ๋‚ด๋ถ€ ๊ตฌ์กฐ ํ™•์ธ
jar tf my-app.jar | head -20

7. ์‹ค๋ฌด์—์„œ ์ฃผ์˜ํ•  ์ 

์„œ๋น„์Šค ํŒŒ์ผ ๋ณ‘ํ•ฉ (SPI)

Java์˜ ServiceLoader๋Š” META-INF/services/ ์•„๋ž˜ ํŒŒ์ผ์„ ์ฝ์–ด ๊ตฌํ˜„์ฒด๋ฅผ ์ฐพ๋Š”๋‹ค. Fat JAR๋กœ ํ•ฉ์น  ๋•Œ ์—ฌ๋Ÿฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๊ฐ™์€ ์„œ๋น„์Šค ํŒŒ์ผ์„ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉด ํ•˜๋‚˜๋งŒ ๋‚จ๊ณ  ๋‚˜๋จธ์ง€๊ฐ€ ์‚ฌ๋ผ์ง„๋‹ค.

<!-- maven-shade-plugin: ์„œ๋น„์Šค ํŒŒ์ผ ๋ณ‘ํ•ฉ ์„ค์ • -->
<transformers>
  <transformer implementation=
    "org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
// Gradle Shadow: ์„œ๋น„์Šค ํŒŒ์ผ ๋ณ‘ํ•ฉ
shadowJar {
    mergeServiceFiles()
}
์„œ๋ช…๋œ JAR ์ฒ˜๋ฆฌ

์ผ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(BouncyCastle ๋“ฑ)๋Š” JAR์— ์„œ๋ช…์ด ๋˜์–ด ์žˆ๋‹ค. Fat JAR๋กœ ํ•ฉ์น˜๋ฉด ์„œ๋ช…์ด ๊นจ์ง€๋ฉด์„œ SecurityException์ด ๋ฐœ์ƒํ•œ๋‹ค.

<!-- ์„œ๋ช… ํŒŒ์ผ ์ œ์™ธ -->
<filters>
  <filter>
    <artifact>*:*</artifact>
    <excludes>
      <exclude>META-INF/*.SF</exclude>
      <exclude>META-INF/*.DSA</exclude>
      <exclude>META-INF/*.RSA</exclude>
    </excludes>
  </filter>
</filters>
Fat JAR ์ค‘๋ณต ๋ฐฐํฌ ๊ธˆ์ง€

๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํฌํ•จํ•˜๋Š” Fat JAR๊ณผ Thin JAR์„ ๋™์‹œ์— ํด๋ž˜์ŠคํŒจ์Šค์— ์˜ฌ๋ฆฌ๋ฉด ํด๋ž˜์Šค๊ฐ€ ๋‘ ๋ฒŒ ๋กœ๋“œ๋˜๋ฉด์„œ ์˜ˆ์ธก ๋ถˆ๊ฐ€๋Šฅํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.


Flink SQL Connector๋Š” ์„ค์น˜ ํŽธ์˜๋ฅผ ์œ„ํ•ด Fat JAR ํ˜•ํƒœ๋กœ ๋ฐฐํฌ๋œ๋‹ค.

  • $FLINK_HOME/lib์—๋Š” Fat JAR๋งŒ ๋‘๊ณ , Thin JAR์€ ์ œ๊ฑฐํ•œ๋‹ค
  • DataStream API์—์„œ Kafka client ๋ฒ„์ „์„ ์„ธ๋ฐ€ํ•˜๊ฒŒ ์ œ์–ดํ•˜๋ ค๋ฉด Thin JAR + ๋ช…์‹œ์  ์˜์กด ์„ ์–ธ์„ ์‚ฌ์šฉํ•œ๋‹ค
  • Fat JAR ๋‚ด๋ถ€์— ํŠน์ • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ํฌํ•จ๋๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•:
jar tf flink-sql-connector-kafka-3.2.0-1.18.jar | grep org/apache/kafka | head
  • Fat JAR๊ณผ Thin JAR์„ ๋™์‹œ์— lib/์— ๋„ฃ์œผ๋ฉด ์ค‘๋ณต ํด๋ž˜์Šค ๋กœ๋”ฉ์œผ๋กœ NoSuchMethodError, ClassNotFoundException ์œ„ํ—˜์ด ์žˆ๋‹ค

9. ํ•œ๋ˆˆ์— ์ •๋ฆฌ

๊ฐœ๋…ํ•ต์‹ฌ
Fat JAR์˜์กด์„ฑ ํฌํ•จ, ๋‹จ์ผ ํŒŒ์ผ ๋ฐฐํฌ, ํฌ๊ธฐ ํผ
Thin JAR์ž๊ธฐ ์ฝ”๋“œ๋งŒ, ๊ฐ€๋ฒผ์›€, ์™ธ๋ถ€ ์˜์กด์„ฑ ํ•„์š”
ShadingFat JAR ๋‚ด๋ถ€ ํŒจํ‚ค์ง€ ๊ฒฝ๋กœ ์žฌ๋ฐฐ์น˜๋กœ ์ถฉ๋Œ ๋ฐฉ์ง€
Spring Boot JAR์˜์กด JAR์„ ํ’€์ง€ ์•Š๊ณ  ์›๋ณธ ๊ทธ๋Œ€๋กœ ๋‚ด์žฅ, ์ปค์Šคํ…€ ๋กœ๋” ์‚ฌ์šฉ
SPI ๋ณ‘ํ•ฉFat JAR ๋นŒ๋“œ ์‹œ META-INF/services/ ํŒŒ์ผ ๋ณ‘ํ•ฉ ํ•„์ˆ˜