Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8701f5d459 | |||
| eaf1416e13 | |||
| c0c1544350 | |||
| d20ac6290b |
+28
-4
@@ -51,13 +51,28 @@ dependencies {
|
|||||||
|
|
||||||
api 'commons-collections:commons-collections:3.2.2'
|
api 'commons-collections:commons-collections:3.2.2'
|
||||||
|
|
||||||
api 'org.apache.poi:poi-excelant:3.9'
|
// poi-excelant -> poi-ooxml -> dom4j:dom4j:1.6.1 (구 groupId) 전이 차단.
|
||||||
|
// 1.6.1 은 XXE(CVE-2020-10683) / XML 인젝션(CVE-2018-1000632) 대상이고,
|
||||||
|
// 소스의 org.dom4j 사용처(HttpClient*AdapterServiceRest 등의 SAXReader)는
|
||||||
|
// hibernate-envers 가 가져오는 org.dom4j:dom4j:2.1.3 과 패키지가 같아 그대로 동작한다.
|
||||||
|
// 두 jar 가 공존하면 WEB-INF/lib 로딩 순서에 따라 1.6.1 이 선택될 수 있으므로 제거한다.
|
||||||
|
api ('org.apache.poi:poi-excelant:3.9') {
|
||||||
|
exclude group: 'dom4j', module: 'dom4j'
|
||||||
|
}
|
||||||
|
|
||||||
api group: 'org.apache.commons', name: 'commons-pool2', version: '2.11.1'
|
api group: 'org.apache.commons', name: 'commons-pool2', version: '2.11.1'
|
||||||
api 'commons-codec:commons-codec:1.15'
|
api 'commons-codec:commons-codec:1.15'
|
||||||
|
|
||||||
//api group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: '2.13.1'
|
// jackson-dataformat-xml(2.13.1) 을 jackson-databind 로 치환 (2026-08-27)
|
||||||
compileOnly group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: '2.13.1'
|
//
|
||||||
|
// XmlMapper/JacksonXml* 사용처는 전 소스에 0건이지만, 이 아티팩트가 transformer 의
|
||||||
|
// 유일한 jackson 공급원이었다(전이로 jackson-core/databind 2.13.1 을 끌고 옴).
|
||||||
|
// 그런데 compileOnly 라 WAR 에는 안 들어가고, 런타임은 Ignite 가 끌고 오는 2.12.7 이다.
|
||||||
|
// 이 컴파일(2.13.1)/런타임(2.12.7) skew 때문에 2.13 전용 API 가 컴파일을 통과했고,
|
||||||
|
// 실제로 JacksonUtil.setValue() 가 ArrayNode.set(int, String)(2.13 신규)을 써서
|
||||||
|
// 배열 경로 setText() 시 NoSuchMethodError 가 나는 상태였다.
|
||||||
|
// 런타임에 실제 존재하는 버전을 명시해 컴파일/런타임을 일치시킨다.
|
||||||
|
api group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.12.7'
|
||||||
|
|
||||||
|
|
||||||
compileOnly group: 'xalan', name: 'xalan', version: '2.6.0'
|
compileOnly group: 'xalan', name: 'xalan', version: '2.6.0'
|
||||||
@@ -78,13 +93,22 @@ dependencies {
|
|||||||
//testImplementation files("libs/json-simple-1.1.1-custom-1.2.jar")
|
//testImplementation files("libs/json-simple-1.1.1-custom-1.2.jar")
|
||||||
//testImplementation files("libs/jep-4.j18-md-1.0.jar")
|
//testImplementation files("libs/jep-4.j18-md-1.0.jar")
|
||||||
testImplementation fileTree(dir: 'libs', include: ['*.jar'])
|
testImplementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
testImplementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: '2.13.1'
|
|
||||||
testImplementation 'junit:junit:4.4'
|
testImplementation 'junit:junit:4.4'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
useJUnitPlatform()
|
useJUnitPlatform()
|
||||||
|
|
||||||
|
// TransformEngine/LayoutManager/MessageFactory 는 ApplicationContextProvider 기반의
|
||||||
|
// JVM 전역 싱글턴이다. 한 JVM 에서 여러 테스트 클래스를 돌리면 마지막에 뜬 스프링
|
||||||
|
// 컨텍스트가 앞선 컨텍스트를 덮어써서, 뒤 클래스가 앞 클래스의 레이아웃을 보게 된다
|
||||||
|
// ("cannot create message" 오류). 클래스마다 JVM 을 새로 띄워 격리한다.
|
||||||
|
forkEvery = 1
|
||||||
|
|
||||||
|
// 클래스별 JVM 분리로 느려지는 것을 CPU 코어 수만큼 병렬 실행해 상쇄한다.
|
||||||
|
// 포크마다 별도 JVM(=별도 H2 인메모리 DB)이라 서로 간섭하지 않는다.
|
||||||
|
maxParallelForks = Math.max(1, Runtime.runtime.availableProcessors().intdiv(2))
|
||||||
}
|
}
|
||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
|
|||||||
@@ -50,6 +50,12 @@ public class JSONMessage extends Message {
|
|||||||
|
|
||||||
factory = mapper.getFactory();
|
factory = mapper.getFactory();
|
||||||
factory.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), true);
|
factory.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), true);
|
||||||
|
// 상대가 0 패딩된 코드값을 따옴표 없이(=JSON 숫자로) 보내면 표준 파서는
|
||||||
|
// "Invalid numeric value: Leading zeroes not allowed" 로 거부한다.
|
||||||
|
// 전문 자체를 못 읽는 것보다 받아들이는 쪽이 낫다고 판단해 허용한다.
|
||||||
|
// ⚠ 이 옵션은 00001 을 숫자 1 로 만든다(선행 0 미보존).
|
||||||
|
// 표준전문 경로(common JacksonUtil.newNumberSafeMapper)와 동일한 설정이다.
|
||||||
|
factory.configure(JsonReadFeature.ALLOW_LEADING_ZEROS_FOR_NUMBERS.mappedFeature(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -146,17 +146,17 @@ class GetTrinomialFunctionTest {
|
|||||||
// ─────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("실전 패턴 — true/false 결과값 (JEP 상수 1.0/0.0 반환 검증)")
|
@DisplayName("실전 패턴 — true/false 결과값 (Boolean 타입 반환 검증)")
|
||||||
void testBooleanLiteralReturnValue() {
|
void testBooleanLiteralReturnValue() {
|
||||||
// JEP addStandardConstants()가 true=1.0, false=0.0 으로 등록하는지 확인
|
// JEP addStandardConstants() 에는 true/false 가 없다.
|
||||||
// → 등록되어 있다면 변수 바인딩 없이 숫자로 반환됨
|
// Parser 가 이를 Boolean 으로 직접 등록하므로(Parser.addBooleanConstants),
|
||||||
// → 등록 안 됐다면 파싱 오류 또는 undeclared 변수(NaN)로 처리됨
|
// 결과값은 숫자 1.0/0.0 이 아니라 Boolean 이다. setUp 도 동일하게 바인딩한다.
|
||||||
jep.addVariable("intVal", 10.0);
|
jep.addVariable("intVal", 10.0);
|
||||||
Object result = eval("getTrinomial(intVal, 10, \"=\", true, false)");
|
Object result = eval("getTrinomial(intVal, 10, \"=\", true, false)");
|
||||||
assertTrue(result instanceof Number,
|
assertTrue(result instanceof Boolean,
|
||||||
"true/false 결과값이 Number 타입이어야 함 (실제: " + result.getClass().getSimpleName() + ")");
|
"true/false 결과값이 Boolean 타입이어야 함 (실제: " + result.getClass().getSimpleName() + ")");
|
||||||
assertEquals(1.0, ((Number) result).doubleValue(), 0.0,
|
assertEquals(Boolean.TRUE, result,
|
||||||
"조건 참일 때 true(=1.0) 반환 기대");
|
"조건 참일 때 true 반환 기대");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -197,9 +197,9 @@ class GetTrinomialFunctionTest {
|
|||||||
assertFalse(jep.hasError(), "평가 오류: " + jep.getErrorInfo());
|
assertFalse(jep.hasError(), "평가 오류: " + jep.getErrorInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
assertTrue(result instanceof Number,
|
assertTrue(result instanceof Boolean,
|
||||||
"결과값이 Number 타입이어야 함 (실제: " + (result == null ? "null" : result.getClass().getSimpleName()) + ")");
|
"결과값이 Boolean 타입이어야 함 (실제: " + (result == null ? "null" : result.getClass().getSimpleName()) + ")");
|
||||||
assertEquals(1.0, ((Number) result).doubleValue(), 0.0,
|
assertEquals(Boolean.TRUE, result,
|
||||||
"INT_VALUE=10, 비교값=10, 연산자=등호 → 참(true=1.0) 반환 기대");
|
"INT_VALUE=10, 비교값=10, 연산자=등호 → 참(true) 반환 기대");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class LayoutRepositoryTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFindById() {
|
void testFindById() {
|
||||||
LayoutEntity layoutEntity = layoutLoaderRepository.getReferenceById("TST_TTST00000002_RES");
|
LayoutEntity layoutEntity = layoutLoaderRepository.getReferenceById("TST_TOSSTEST1_TGT");
|
||||||
layoutEntity = layoutEntity.getLayoutItemEntities().stream().findAny().get().getLayoutEntity();
|
layoutEntity = layoutEntity.getLayoutItemEntities().stream().findAny().get().getLayoutEntity();
|
||||||
assertNotNull(layoutEntity);
|
assertNotNull(layoutEntity);
|
||||||
System.out.println(layoutEntity);
|
System.out.println(layoutEntity);
|
||||||
|
|||||||
Reference in New Issue
Block a user