[Groovy Script] (4) - 리팩토링 및 jar파일 만들기
-----------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------
목표
- 테스트코드 작성
- CleanCode 만들기
- jar파일과 script파일을 분리하여 라이브러리를 제공하는 것
1) 바탕화면에 Greetings 폴더를 만들고 프로젝트의 groovyscript 패키지를 옮겨줍니다.
2) 패키지를 옮겨주고 이클립스 상의 groovyscript 패키지를 지웁니다.
3) 그리고 실행하면 당연히 에러가 납니다.......( 절대 주소로 수정 )
JavaFile.java 파일을 보시면 다음과 같이 프로젝트의 상대주소로 groovy를 가져옵니다.
Class groovyClass = loader.parseClass(new File("src/groovyscript/GroovyScript.groovy"));
아까 만들어준 바탕화면의 Greetings폴더 아래 각자에 맞는 GroovyScript.groovy파일의
Path를 잡아줍니다.
Class groovyClass = loader.parseClass(new File("C:/Users/송원석/Desktop/Greetings/groovyscript/GroovyScript.groovy"));
4) 일단 성공!
5) main함수명 바꾸기
우리의 목표는 계속 말하고 있지만...jar 라이브러리 파일을 만드는 것입니다!
그러기 위해 다음과 같이 3가지를 변경해 줍니다.
- main함수를 sayGreetings라는 이름의 함수로 바꿔줍니다.
- String을 return해줍니다.
- args1배열을 String name값으로 받아옵니다.
---------------------------------------------------------------------------------------------------
public static void main(String[] args) throws CompilationFailedException, IOException, InstantiationException, IllegalAccessException { ClassLoader parent = JavaFile.class.getClassLoader(); GroovyClassLoader loader = new GroovyClassLoader(parent); Class groovyClass = loader.parseClass(new File("C:/Users/송원석/Desktop/Greetings/groovyscript/GroovyScript.groovy")); GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance(); Object[] args1 = {"소심한개발자"}; String groovyResult = (String) groovyObject.invokeMethod("hiGroovy", args1); System.out.println(groovyResult); }
---------------------------------------------------------------------------------------------------
⬇️
---------------------------------------------------------------------------------------------------
public String sayGreetings(String name) throws CompilationFailedException, IOException, InstantiationException, IllegalAccessException { ClassLoader parent = JavaFile.class.getClassLoader(); GroovyClassLoader loader = new GroovyClassLoader(parent); Class groovyClass = loader.parseClass(new File("C:/Users/송원석/Desktop/Greetings/groovyscript/GroovyScript.groovy")); GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance(); String groovyResult = (String) groovyObject.invokeMethod("hiGroovy", name); return groovyResult; }
---------------------------------------------------------------------------------------------------
6) 테스트코드 작성하기
이렇게 소스코드의 수정사항이 많아지면 소스가 제대로 동작하는지 확인하기 힘들어집니다.
그래서 TDD를 해야되는데 블로깅하려고....main함수 부터...
(주저리 주저리...)
다음과 같이 test패키지를 만들어주고 JavaFileTest.java파일을 만들어 줍니다.
Junit을 추가해주고
다음과 같이 테스트 코드를 만듭니다.
---------------------------------------------------------------------------------------------------
package test; import static org.junit.Assert.assertEquals; import org.junit.jupiter.api.Test; import javafile.JavaFile; public class JavaFileTest { JavaFile jf=new JavaFile(); @Test public void sayGreetingsTest() { String result=jf.sayGreetings("소심한개발자"); assertEquals(result,"소심한개발자 Hi"); } }
---------------------------------------------------------------------------------------------------
근데.....에러가 난다...
우리가
sayGreetings 함수를 만들때 throws했던 예외를 처리하라는 것......
일단 테스트를 통과하는 것이 중요하기 때문에
sayGreetings(String name) 함수의 throws를 모두 지워주고 함수에 try catch문을 작성해줍니다.
---------------------------------------------------------------------------------------------------
public String sayGreetings(String name) { ClassLoader parent = JavaFile.class.getClassLoader(); GroovyClassLoader loader = new GroovyClassLoader(parent); Class groovyClass = null; try { groovyClass = loader.parseClass(new File("C:/Users/송원석/Desktop/Greetings/groovyscript/GroovyScript.groovy")); } catch (CompilationFailedException | IOException e) { e.printStackTrace(); } GroovyObject groovyObject = null; try { groovyObject = (GroovyObject) groovyClass.newInstance(); } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); } String groovyResult = (String) groovyObject.invokeMethod("hiGroovy", name); return groovyResult; }
---------------------------------------------------------------------------------------------------
이제 try catch문을 지우기 위해 프록시 패턴(Proxy Pattern)을 사용해 보겠습니다.
javafile의 패키지명을 main.greetings로 변경하고
javafile패키지에 다음과 같이 클래스와 인터페이스를 추가해줍니다.
Greetings.java 인터페이스
---------------------------------------------------------------------------------------------------
package main.greetings; import java.io.IOException; import org.codehaus.groovy.control.CompilationFailedException; public interface Greetings { public String sayGreetings(String name) throws CompilationFailedException, IOException, InstantiationException, IllegalAccessException; }
---------------------------------------------------------------------------------------------------
GreetingsExceptionHandler.java 클래스 (Greetings 구현체)
---------------------------------------------------------------------------------------------------
package main.greetings; import java.io.IOException; import org.codehaus.groovy.control.CompilationFailedException; public class GreetingsExceptionHandler implements Greetings{ Greetings gt = new GreetingsImpl(); @Override public String sayGreetings(String name) { String result = ""; try { result = gt.sayGreetings(name); } catch (CompilationFailedException | InstantiationException | IllegalAccessException | IOException e) { e.printStackTrace(); } return result; } }
---------------------------------------------------------------------------------------------------
GreetingsImpl.java 클래스 (Greetings 구현체)
---------------------------------------------------------------------------------------------------
package main.greetings; import java.io.File; import java.io.IOException; import org.codehaus.groovy.control.CompilationFailedException; import groovy.lang.GroovyClassLoader; import groovy.lang.GroovyObject; public class GreetingsImpl implements Greetings{ public String sayGreetings(String name) throws CompilationFailedException, IOException, InstantiationException, IllegalAccessException{ ClassLoader parent = GreetingsImpl.class.getClassLoader(); GroovyClassLoader loader = new GroovyClassLoader(parent); Class<?> groovyClass = null; groovyClass = loader.parseClass(new File("C:/Users/송원석/Desktop/Greetings/groovyscript/GroovyScript.groovy")); GroovyObject groovyObject = null; groovyObject = (GroovyObject) groovyClass.newInstance(); String groovyResult = (String) groovyObject.invokeMethod("hiGroovy", name); return groovyResult; } }
---------------------------------------------------------------------------------------------------
왜냐하면 GreetingsImpl을 직접사용했기 때문입니다.
그러면 이제 GreetingsExceptionHandler로 테스트코드를 바꿔줍니다.
편안.........
이 프로그램은 이름과 groovy 스트립트의 주소를 입력 받고 스크립트의 변경사항으로
인사를 하는 프로그램입니다...
[Groovy Script] (2) 에서 만들어줬던 Groovy파일을 수정해줍니다.
---------------------------------------------------------------------------------------------------
package groovyscript class GroovyScript { public String hiGroovy(String item) { return item + " Hi"; } public String helloGroovy(String item) { return item + " Hello"; } }
---------------------------------------------------------------------------------------------------
⬇️
---------------------------------------------------------------------------------------------------
package script class GroovyScript { public String sayGroovy(String item){ return item + " Hello"; } }
---------------------------------------------------------------------------------------------------
물론 이것에 맞춰서 GreetingImpl.java파일의 invokeMethod의 함수명도
sayGroovy로 바꿔줍니다.
소스를 바꿨으니 Junit테스트!
아.....Hello....
편안......
이제 groovy스트립트의 주소값을 입력받을 수 있게 String groovyPath값을 함수에 추가해줍니다.
---------------------------------------------------------------------------------------------------
public String sayGreetings(String name, String groovyPath) throws CompilationFailedException, IOException, InstantiationException, IllegalAccessException{ ClassLoader parent = GreetingsImpl.class.getClassLoader(); GroovyClassLoader loader = new GroovyClassLoader(parent); Class<?> groovyClass = loader.parseClass(new File(groovyPath)); GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance(); String groovyResult = (String) groovyObject.invokeMethod("sayGroovy", name); return groovyResult; }
---------------------------------------------------------------------------------------------------
테스트 코드도 그에 맞춰서 변경
@Test
public void javaFileTest() {
String result=jf.sayGreetings("소심한개발자", "C:/Users/송원석/Desktop/Greetings/script/GroovyScript.groovy");
assertEquals(result,"소심한개발자 Hi");
}
그러면 이제 이름과 Script의 주소값을 입력받아 인사해주는 프로그램이 완성되었습니다!
7) jar 만들기
groovyTest.jar를 만들어줬습니다!
이제 이클립스에서 새로운 workspace를 열고
groovy-all-2.4.7.jar와
groovyTest.jar를 추가해주고 다음과 같이 소스코딩을 해줍니다.
끝!
8) Script의 변경에 따라 결과 값이 달라지는 것을 확인할 수 있습니다!!!!!
Comments
Post a Comment