Java의 Nashorn 자바스크립트 엔진 활용하기 🚀

2025년 최신 트렌드로 알아보는 Nashorn의 모든 것!
안녕! 오늘은 Java의 숨겨진 보석 같은 기능인 Nashorn 자바스크립트 엔진에 대해 함께 알아볼 거야. 자바와 자바스크립트를 함께 사용하면 어떤 마법 같은 일이 벌어질까? 🧙♂️ 지금부터 Nashorn의 세계로 함께 떠나보자!
🔍 Nashorn이 뭐길래? 기본 개념 알아보기
Nashorn(나스호른)은 독일어로 '코뿔소'라는 뜻이야. 왜 코뿔소 이름을 붙였을까? 아마도 강력하고 빠른 성능을 상징하기 위해서겠지! 😄
Nashorn은 Java 8에서 처음 도입된 자바스크립트 엔진으로, 기존의 Rhino 엔진을 대체했어. Java 가상 머신(JVM) 위에서 자바스크립트 코드를 실행할 수 있게 해주는 엔진이지. 이게 왜 중요하냐고? Java의 강력한 기능과 자바스크립트의 유연성을 함께 사용할 수 있다는 거야! 🎯
2025년 현재, Nashorn은 Java 15부터 공식적으로 deprecated 되었지만, 여전히 많은 레거시 시스템과 특수 용도에서 활용되고 있어. 또한 Nashorn의 개념과 활용법을 이해하면 최신 GraalVM의 JavaScript 엔진도 쉽게 이해할 수 있지!
📌 Nashorn의 주요 특징
- JVM 위에서 자바스크립트 실행 가능
- Java와 JavaScript 간 쉬운 상호 운용성
- jjs 명령줄 도구 제공
- ECMAScript 5.1 표준 지원
- Java 8부터 기본 탑재 (Java 15부터 deprecated)
⚙️ Nashorn 시작하기: 기본 설정과 사용법
자, 이제 Nashorn을 어떻게 사용하는지 알아볼까? Java 프로젝트에서 Nashorn을 사용하는 건 생각보다 정말 간단해! 😊
1. 기본 설정
Java 8부터 Java 14까지는 별도의 설치 없이 바로 사용할 수 있어. 다음 import만 추가하면 돼:
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
2. 간단한 자바스크립트 실행하기
다음은 Nashorn을 사용해 간단한 자바스크립트 코드를 실행하는 예제야:
public class NashornDemo {
public static void main(String[] args) throws ScriptException {
// Nashorn 엔진 생성
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// 자바스크립트 코드 실행
Object result = engine.eval("'안녕, Nashorn! ' + (5 + 3)");
System.out.println(result); // 출력: 안녕, Nashorn! 8
}
}
정말 간단하지? ScriptEngineManager로 Nashorn 엔진을 가져오고, eval() 메소드로 자바스크립트 코드를 실행하면 끝이야! 🎉
🔄 Java와 JavaScript 간의 데이터 교환
Nashorn의 진짜 매력은 Java와 JavaScript 사이에서 데이터를 주고받을 수 있다는 점이야. 이건 정말 강력한 기능이지! 🚀
1. Java에서 JavaScript로 데이터 전달하기
Java 객체나 변수를 JavaScript에 전달하는 방법을 알아보자:
import javax.script.*;
import java.util.*;
public class DataExchangeDemo {
public static void main(String[] args) throws ScriptException {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// Java 데이터 생성
List<String> fruits = new ArrayList<>();
fruits.add("사과");
fruits.add("바나나");
fruits.add("오렌지");
// JavaScript에 데이터 바인딩
Bindings bindings = engine.createBindings();
bindings.put("fruitList", fruits);
engine.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
// JavaScript에서 Java 데이터 사용
String script = "print('과일 목록: ' + fruitList);" +
"print('첫 번째 과일: ' + fruitList[0]);" +
"var fruitCount = fruitList.size();" +
"print('과일 개수: ' + fruitCount);";
engine.eval(script);
}
}
Bindings 객체를 사용하면 Java의 데이터를 JavaScript에서 쉽게 접근할 수 있어. 위 예제에서는 Java의 ArrayList를 JavaScript에 전달했고, JavaScript에서는 이 리스트를 마치 배열처럼 사용할 수 있어! 👍
2. JavaScript에서 Java로 결과 반환하기
이번엔 JavaScript에서 계산한 결과를 Java로 가져와 보자:
public class ReturnDataDemo {
public static void main(String[] args) throws ScriptException {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// JavaScript에서 계산 후 결과 반환
String script = "var result = 0;" +
"for(var i = 1; i <= 10; i++) {" +
" result += i;" +
"}" +
"result;"; // 마지막 값이 반환됨
Object sum = engine.eval(script);
System.out.println("1부터 10까지의 합: " + sum); // 출력: 55
// JavaScript 객체 생성 후 Java로 가져오기
String objectScript = "var person = {" +
" name: '홍길동'," +
" age: 25," +
" greeting: function() { return '안녕하세요, ' + this.name + '입니다!'; }" +
"};" +
"person;";
Object personObj = engine.eval(objectScript);
// Nashorn의 ScriptObjectMirror로 JavaScript 객체 다루기
jdk.nashorn.api.scripting.ScriptObjectMirror person =
(jdk.nashorn.api.scripting.ScriptObjectMirror) personObj;
System.out.println("이름: " + person.get("name"));
System.out.println("나이: " + person.get("age"));
System.out.println("인사: " + person.callMember("greeting"));
}
}
JavaScript에서 생성한 객체는 ScriptObjectMirror 클래스를 통해 Java에서 접근할 수 있어. 이렇게 하면 JavaScript 객체의 속성과 메소드를 Java에서도 사용할 수 있지! 😎
🛠️ 실용적인 Nashorn 활용 사례
이론은 충분히 알아봤으니, 이제 Nashorn을 실제로 어떻게 활용할 수 있는지 몇 가지 재미있는 예제를 통해 알아보자! 🎮
1. 동적 스크립트 평가 및 실행
런타임에 사용자 입력이나 외부 소스에서 가져온 스크립트를 동적으로 실행할 수 있어:
import javax.script.*;
import java.util.Scanner;
public class DynamicScriptDemo {
public static void main(String[] args) {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
Scanner scanner = new Scanner(System.in);
System.out.println("계산할 수식을 입력하세요 (예: 2 + 2 * 3):");
String expression = scanner.nextLine();
try {
Object result = engine.eval(expression);
System.out.println("계산 결과: " + result);
} catch (ScriptException e) {
System.out.println("오류 발생: " + e.getMessage());
}
scanner.close();
}
}
이 예제는 간단한 계산기처럼 작동해. 사용자가 입력한 수식을 Nashorn이 평가하고 결과를 반환하지. 이런 방식으로 동적 규칙 엔진이나 사용자 정의 스크립트 실행 환경을 만들 수 있어! 🧮
2. 템플릿 엔진 구현하기
Nashorn을 사용해 간단한 템플릿 엔진을 만들 수도 있어:
import javax.script.*;
import java.util.*;
public class TemplateEngineDemo {
public static void main(String[] args) throws ScriptException {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// 템플릿 데이터
Map<String, Object> data = new HashMap<>();
data.put("name", "김자바");
data.put("company", "재능넷");
data.put("skills", Arrays.asList("Java", "JavaScript", "Nashorn"));
// 템플릿 문자열
String template = "안녕하세요, ${name}님!\n" +
"${company}에서 근무하시는군요.\n" +
"보유 기술: ${skills.join(', ')}";
// 템플릿 처리 스크립트
String script = "function processTemplate(template, data) {" +
" return template.replace(/\\${([^}]+)}/g, function(match, expr) {" +
" return eval('data.' + expr);" +
" });" +
"}" +
"processTemplate(template, data);";
// Nashorn에 데이터 바인딩
Bindings bindings = engine.createBindings();
bindings.put("template", template);
bindings.put("data", data);
engine.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
// 템플릿 처리 및 결과 출력
String result = (String) engine.eval(script);
System.out.println(result);
}
}
이 예제는 간단한 템플릿 엔진을 구현한 거야. JavaScript의 정규식과 문자열 처리 기능을 활용해 템플릿에 데이터를 채워넣었어. 재능넷 같은 플랫폼에서 동적 콘텐츠 생성에 이런 방식을 활용할 수 있지! 📝
3. 자바 애플리케이션에 스크립트 기능 추가하기
사용자가 직접 스크립트를 작성해 애플리케이션의 동작을 확장할 수 있게 해보자:
import javax.script.*;
import java.io.*;
public class ScriptableAppDemo {
// 사용자 정의 클래스
public static class Calculator {
public double add(double a, double b) { return a + b; }
public double subtract(double a, double b) { return a - b; }
public double multiply(double a, double b) { return a * b; }
public double divide(double a, double b) { return a / b; }
}
public static void main(String[] args) {
try {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// Java 객체를 JavaScript에 노출
Calculator calc = new Calculator();
engine.put("calculator", calc);
// 사용자 스크립트 파일 읽기 (예시)
String userScript = "// 사용자 정의 함수\n" +
"function calculateArea(radius) {\n" +
" return Math.PI * radius * radius;\n" +
"}\n\n" +
"// 기본 계산기 기능 사용\n" +
"var sum = calculator.add(10, 20);\n" +
"print('10 + 20 = ' + sum);\n\n" +
"// 사용자 정의 함수 사용\n" +
"var radius = 5;\n" +
"var area = calculateArea(radius);\n" +
"print('반지름이 ' + radius + '인 원의 넓이: ' + area.toFixed(2));\n";
// 스크립트 실행
engine.eval(userScript);
// 사용자 정의 함수 Java에서 호출
Invocable invocable = (Invocable) engine;
Object result = invocable.invokeFunction("calculateArea", 10);
System.out.println("Java에서 호출: 반지름이 10인 원의 넓이: " + result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
이 예제에서는 Java 애플리케이션에 스크립팅 기능을 추가했어. 사용자가 작성한 JavaScript 함수를 Java 코드에서 직접 호출할 수도 있지. 이런 방식으로 플러그인 시스템이나 확장 가능한 애플리케이션을 구현할 수 있어! 🔌
📊 Nashorn의 성능과 최적화
Nashorn을 실제 프로젝트에 적용하기 전에 성능 특성과 최적화 방법도 알아두면 좋을 것 같아! 🏎️
1. 스크립트 컴파일 캐싱
반복적으로 같은 스크립트를 실행한다면, 매번 컴파일하지 말고 미리 컴파일해두는 것이 좋아:
import javax.script.*;
public class CompiledScriptDemo {
public static void main(String[] args) {
try {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// 컴파일 가능한 엔진으로 캐스팅
Compilable compilable = (Compilable) engine;
// 스크립트 컴파일
String script = "function factorial(n) { " +
" if (n <= 1) return 1; " +
" return n * factorial(n-1); " +
"} " +
"factorial(n);";
CompiledScript compiledScript = compilable.compile(script);
// 여러 번 실행 (다른 매개변수로)
long startTime = System.nanoTime();
for (int i = 1; i <= 20; i++) {
Bindings bindings = engine.createBindings();
bindings.put("n", i);
Object result = compiledScript.eval(bindings);
System.out.println(i + "! = " + result);
}
long endTime = System.nanoTime();
System.out.println("실행 시간: " + (endTime - startTime) / 1_000_000 + "ms");
} catch (Exception e) {
e.printStackTrace();
}
}
}
CompiledScript를 사용하면 스크립트를 한 번만 컴파일하고 여러 번 재사용할 수 있어. 이는 반복적으로 스크립트를 실행할 때 성능을 크게 향상시켜줘! 🚀
2. 타입 힌트 사용하기
JavaScript는 동적 타입 언어지만, Nashorn에서는 타입 힌트를 제공해 성능을 개선할 수 있어:
// 타입 힌트가 없는 함수
var slowSum = function(a, b) {
return a + b;
};
// 타입 힌트가 있는 함수
var fastSum = function(a, b) {
"use strict";
// @param {int} a
// @param {int} b
// @returns {int}
return a + b;
};
주석으로 타입 힌트를 제공하면 Nashorn이 최적화된 코드를 생성할 수 있어. 특히 숫자 계산이 많은 코드에서 성능 차이가 크게 나타날 수 있지! 🔢
3. 멀티스레딩 환경에서의 Nashorn
Nashorn 엔진은 기본적으로 스레드 안전하지 않아. 멀티스레드 환경에서는 각 스레드마다 별도의 엔진 인스턴스를 생성해야 해:
import javax.script.*;
import java.util.concurrent.*;
public class ThreadSafeNashornDemo {
public static void main(String[] args) {
// 스레드 풀 생성
ExecutorService executor = Executors.newFixedThreadPool(4);
// 여러 작업 제출
for (int i = 0; i < 10; i++) {
final int taskId = i;
executor.submit(() -> {
try {
// 각 스레드마다 새로운 엔진 인스턴스 생성
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// 스크립트 실행
engine.put("taskId", taskId);
Object result = engine.eval("'Task ' + taskId + ' 실행 중: ' + Math.random()");
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
});
}
// 스레드 풀 종료
executor.shutdown();
try {
executor.awaitTermination(1, TimeUnit.MINUTES);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
각 스레드마다 별도의 ScriptEngine 인스턴스를 생성하면 멀티스레드 환경에서도 안전하게 Nashorn을 사용할 수 있어! 🧵
🔒 보안 고려사항과 제한사항
Nashorn을 사용할 때는 보안 측면도 반드시 고려해야 해. 특히 외부에서 제공된 스크립트를 실행할 때는 더욱 주의가 필요해! 🛡️
1. 보안 관리자 설정
Java의 SecurityManager를 사용해 스크립트의 권한을 제한할 수 있어:
import javax.script.*;
import java.security.*;
public class SecurityDemo {
public static void main(String[] args) {
try {
// 보안 관리자 설정
System.setSecurityManager(new SecurityManager());
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
try {
// 파일 시스템 접근 시도
engine.eval("var file = new java.io.File('/etc/passwd'); print(file.exists());");
} catch (Exception e) {
System.out.println("보안 예외 발생: " + e.getMessage());
}
// 안전한 연산은 허용
Object result = engine.eval("'안전한 계산: ' + (2 + 2)");
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
SecurityManager를 설정하면 스크립트가 파일 시스템이나 네트워크 같은 민감한 리소스에 접근하는 것을 제한할 수 있어. 이는 외부 스크립트를 실행할 때 특히 중요해! 🔐
2. 클래스 필터링
스크립트에서 접근할 수 있는 Java 클래스를 제한할 수도 있어:
import jdk.nashorn.api.scripting.ClassFilter;
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
import javax.script.*;
public class ClassFilterDemo {
// 클래스 필터 구현
static class MyClassFilter implements ClassFilter {
@Override
public boolean exposeToScripts(String className) {
// java.util 패키지는 허용, java.io와 java.net은 거부
return className.startsWith("java.util") &&
!className.startsWith("java.io") &&
!className.startsWith("java.net");
}
}
public static void main(String[] args) {
try {
// 필터가 적용된 Nashorn 엔진 생성
NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
ScriptEngine engine = factory.getScriptEngine(new MyClassFilter());
// 허용된 클래스 사용
engine.eval("var list = new java.util.ArrayList(); " +
"list.add('항목 1'); " +
"print('ArrayList 사용: ' + list);");
try {
// 거부된 클래스 사용 시도
engine.eval("var file = new java.io.File('test.txt');");
} catch (Exception e) {
System.out.println("예상된 예외 발생: " + e.getMessage());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
ClassFilter를 구현하면 스크립트에서 접근할 수 있는 Java 클래스를 명시적으로 제한할 수 있어. 이렇게 하면 스크립트가 민감한 시스템 기능에 접근하는 것을 방지할 수 있지! 🚫
3. 타임아웃 설정
무한 루프 같은 악의적인 스크립트로부터 시스템을 보호하기 위해 실행 시간 제한을 설정할 수 있어:
import javax.script.*;
import java.util.concurrent.*;
public class TimeoutDemo {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// 무한 루프 스크립트
String infiniteLoopScript = "while(true) { }";
Future<Object> future = executor.submit(() -> {
try {
return engine.eval(infiniteLoopScript);
} catch (ScriptException e) {
return e.getMessage();
}
});
try {
// 3초 타임아웃 설정
Object result = future.get(3, TimeUnit.SECONDS);
System.out.println("결과: " + result);
} catch (TimeoutException e) {
System.out.println("스크립트 실행 시간이 너무 깁니다. 중단합니다.");
future.cancel(true);
} catch (Exception e) {
e.printStackTrace();
}
executor.shutdownNow();
}
}
ExecutorService와 Future를 사용하면 스크립트 실행 시간을 제한할 수 있어. 이렇게 하면 무한 루프나 리소스를 과도하게 사용하는 스크립트로부터 시스템을 보호할 수 있지! ⏱️
🔄 Nashorn의 대안과 미래
Nashorn이 Java 15부터 deprecated 되었다고 했지? 그렇다면 대안은 무엇이고, 앞으로 어떻게 발전할까? 🔮
1. GraalVM JavaScript
Nashorn의 가장 강력한 대안은 GraalVM의 JavaScript 엔진이야:
// Maven 의존성
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js</artifactId>
<version>23.0.0</version>
</dependency>
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js-scriptengine</artifactId>
<version>23.0.0</version>
</dependency>
GraalVM JavaScript는 ECMAScript 2022 표준을 지원하고, Nashorn보다 훨씬 뛰어난 성능을 제공해. 또한 Node.js 모듈도 사용할 수 있어서 호환성이 매우 뛰어나지! 💪
import org.graalvm.polyglot.*;
import org.graalvm.polyglot.proxy.*;
public class GraalJSDemo {
public static void main(String[] args) {
try (Context context = Context.create("js")) {
// JavaScript 코드 실행
Value result = context.eval("js", "({ message: '안녕, GraalVM!', answer: 42 })");
// JavaScript 객체의 속성 접근
System.out.println(result.getMember("message").asString()); // 안녕, GraalVM!
System.out.println(result.getMember("answer").asInt()); // 42
// Java 객체를 JavaScript에 바인딩
context.getBindings("js").putMember("javaObj", new MyJavaClass());
// JavaScript에서 Java 메소드 호출
context.eval("js", "javaObj.hello('GraalVM 사용자')");
}
}
static class MyJavaClass {
public void hello(String name) {
System.out.println("Java에서 인사: 안녕하세요, " + name + "님!");
}
}
}
GraalVM은 다양한 언어를 지원하는 폴리글랏 가상 머신이야. JavaScript 외에도 Python, Ruby, R 등 여러 언어를 함께 사용할 수 있지! 🌐
2. 다른 대안들
Nashorn 외에도 Java에서 JavaScript를 실행할 수 있는 다른 방법들이 있어:
- Rhino: Nashorn 이전에 사용되던 Mozilla의 JavaScript 엔진
- J2V8: V8 JavaScript 엔진의 Java 바인딩
- TeaVM: Java 코드를 JavaScript로 변환하는 도구
- Vert.x: JavaScript를 포함한 다양한 언어를 지원하는 이벤트 기반 프레임워크
각 도구마다 장단점이 있으니, 프로젝트의 요구사항에 맞는 도구를 선택하는 것이 중요해! 🔧
3. 2025년 현재 JavaScript와 Java 통합의 미래
2025년 현재, JavaScript와 Java의 통합은 더욱 발전하고 있어:
- ✅ GraalVM이 표준 JDK에 통합되는 움직임
- ✅ WebAssembly를 통한 Java와 JavaScript 간의 새로운 상호운용성
- ✅ Project Loom의 가상 스레드와 JavaScript 비동기 프로그래밍 모델의 통합
- ✅ Spring Framework에서 GraalVM JavaScript를 활용한 스크립팅 지원 강화
Java와 JavaScript의 경계는 점점 더 흐려지고 있어. 두 언어의 장점을 결합한 하이브리드 애플리케이션 개발이 더욱 쉬워지고 있지! 🌉
💼 실제 프로젝트에서의 Nashorn 활용 사례
이론적인 내용은 충분히 다뤘으니, 이제 실제 업계에서 Nashorn이 어떻게 활용되고 있는지 알아보자! 🏢
1. 웹 애플리케이션에서의 서버 사이드 렌더링
React, Vue 같은 JavaScript 프레임워크로 만든 UI를 서버에서 렌더링할 때 Nashorn이 사용돼:
import javax.script.*;
import java.io.*;
public class ServerSideRenderingDemo {
public static void main(String[] args) {
try {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// React 라이브러리 로드 (간소화된 예제)
engine.eval(new FileReader("react.js"));
engine.eval(new FileReader("react-dom-server.js"));
// React 컴포넌트 정의
String reactComponent =
"const MyComponent = () => {" +
" return React.createElement('div', null, " +
" React.createElement('h1', null, '안녕하세요, SSR!'), " +
" React.createElement('p', null, '이 페이지는 서버에서 렌더링되었습니다.') " +
" );" +
"};" +
"ReactDOMServer.renderToString(React.createElement(MyComponent));";
// 서버에서 HTML 렌더링
String html = (String) engine.eval(reactComponent);
System.out.println("렌더링된 HTML:");
System.out.println(html);
} catch (Exception e) {
e.printStackTrace();
}
}
}
이 방식으로 JavaScript 프레임워크로 만든 UI를 서버에서 미리 렌더링하면 초기 로딩 속도가 빨라지고 SEO도 개선돼! 🖥️
2. 규칙 엔진 및 비즈니스 로직
복잡한 비즈니스 규칙을 JavaScript로 작성하고 Java 애플리케이션에서 실행하는 사례도 많아:
import javax.script.*;
import java.util.*;
public class BusinessRulesDemo {
// 주문 클래스
static class Order {
private String customerId;
private List<Item> items = new ArrayList<>();
private double totalAmount;
// 생성자, getter, setter 생략...
public void addItem(Item item) {
items.add(item);
totalAmount += item.getPrice() * item.getQuantity();
}
// 기타 메소드 생략...
}
static class Item {
private String productId;
private double price;
private int quantity;
// 생성자, getter, setter 생략...
}
public static void main(String[] args) {
try {
// 주문 생성 (예시)
Order order = new Order();
order.setCustomerId("CUST001");
order.addItem(new Item("PROD001", 29.99, 2));
order.addItem(new Item("PROD002", 49.99, 1));
// Nashorn 엔진 설정
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// 할인 규칙 스크립트 (외부 파일이나 데이터베이스에서 로드 가능)
String discountRules =
"function calculateDiscount(order) {" +
" var discount = 0;" +
" " +
" // 총 주문액이 100달러 이상이면 10% 할인" +
" if (order.totalAmount >= 100) {" +
" discount += order.totalAmount * 0.1;" +
" }" +
" " +
" // VIP 고객이면 추가 5% 할인" +
" if (isVipCustomer(order.customerId)) {" +
" discount += order.totalAmount * 0.05;" +
" }" +
" " +
" return discount;" +
"}" +
"" +
"function isVipCustomer(customerId) {" +
" // 실제로는 데이터베이스 조회 등의 로직이 있을 수 있음" +
" return customerId === 'CUST001';" +
"}";
// 스크립트 평가
engine.eval(discountRules);
// 주문 객체를 JavaScript에 전달
engine.put("order", order);
// 할인 계산 함수 호출
Invocable invocable = (Invocable) engine;
double discount = (double) invocable.invokeFunction("calculateDiscount", order);
// 결과 출력
System.out.println("주문 총액: $" + order.totalAmount);
System.out.println("적용된 할인: $" + discount);
System.out.println("최종 결제 금액: $" + (order.totalAmount - discount));
} catch (Exception e) {
e.printStackTrace();
}
}
}
이런 방식으로 비즈니스 규칙을 Java 코드와 분리하면 개발자가 아닌 사람도 규칙을 수정할 수 있고, 애플리케이션을 재배포하지 않고도 규칙을 업데이트할 수 있어! 📝
3. 플러그인 시스템
사용자가 직접 플러그인을 작성할 수 있는 확장 가능한 애플리케이션을 만들 때도 Nashorn이 유용해:
- 지식인의 숲 - 지적 재산권 보호 고지
지적 재산권 보호 고지
- 저작권 및 소유권: 본 컨텐츠는 재능넷의 독점 AI 기술로 생성되었으며, 대한민국 저작권법 및 국제 저작권 협약에 의해 보호됩니다.
- AI 생성 컨텐츠의 법적 지위: 본 AI 생성 컨텐츠는 재능넷의 지적 창작물로 인정되며, 관련 법규에 따라 저작권 보호를 받습니다.
- 사용 제한: 재능넷의 명시적 서면 동의 없이 본 컨텐츠를 복제, 수정, 배포, 또는 상업적으로 활용하는 행위는 엄격히 금지됩니다.
- 데이터 수집 금지: 본 컨텐츠에 대한 무단 스크래핑, 크롤링, 및 자동화된 데이터 수집은 법적 제재의 대상이 됩니다.
- AI 학습 제한: 재능넷의 AI 생성 컨텐츠를 타 AI 모델 학습에 무단 사용하는 행위는 금지되며, 이는 지적 재산권 침해로 간주됩니다.
재능넷은 최신 AI 기술과 법률에 기반하여 자사의 지적 재산권을 적극적으로 보호하며,
무단 사용 및 침해 행위에 대해 법적 대응을 할 권리를 보유합니다.
© 2025 재능넷 | All rights reserved.
댓글 0개