Project3 - SubProcess & Jpype

2021. 8. 15. 12:58솔트룩스/프로젝트

우리 회사 솔루션은 "java"기반이다.

그런데 이번 프로젝트에서 70%를 담당하는 회사에서는 "python" 으로 개발을 한다고 한다.

그래서 추후 유지보수나, 혹시나 모를 컨소시엄사와의 연동을 고려하여 우리도 python으로 개발을 해야한다는 결론이 나왔다.

 

하지만 이미 우리는 형태소/개체명/인용문/정보원  분석을 java로 끝을 낸  상태였고,

java 기반으로 돌아가는 솔루션이라 python으로 다시 코드를 짜는것은 이 시간적 여유로는 전혀 불가능한 정도였다.

그래서 python에서 java 프로젝트를 호출하여 실행할 수 있는 방법이 없을까 고민을 하였다.

 

첫번째 나의 대안은 SubProcess를 이용한 해결책이였다.하지만 나의 현재 능력으로는 나의 java 프로젝트를  Runnable JAR 파일로 묶고, 이를 python에서 호출하면 java  project의 main에서 실행되고 나서 console에 나오는 결과값을 불러오는 것만 가능했다.

 

하지만 subprocess는 일단 팀장님이 원하는 로직과 결과가 아니였고, 나도 이건 별 의미가 없다고 생각을 했다.

이 라이브러리 사용은 정말 나중에 정 안된다면 사용하는 것으로 하고,

"자바 프로젝트를 불러와서, 원하는 패키지와 클래스 사용하는 방법" 을 찾기 시작했는데 그게 바로 Jpype 였다.

참고로 Jpype란, python에서 JVM을 연결하여 java 와 python을 통신하는 라이브러리다.

 

Analyzer Package
Analyzer Package 는 java project에서 만들어둔 모듈에서 원하는 클래스와 메소드를 호출하여 원하는 결과값을 얻을 수 있게 python에서 모듈화 해둔 패키지이다.
improt jpype
import os
import configoparser

- JVM ON/OFF

class JVM:
	#JVM 연결
	def startJVM():
    	classpath = "JAR 파일 경로"
          try:
              jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.class.path = {calsspath}", format(classpath = classpath), "-Dfile.encoding=UTF*", "-ea", "-Xmx{}m".format(2048), covertString = True)
          except Exception as e:
              print(e)
    
    #JVM 종료
    def closeJVM():
    	jpype.shutdownJVM()

- java 패키지 & 클래스 호출 및 메소드 호출을 통한 결과 반환

class Analyzer:
	def __init__(self, dicPath, content):
    	self.dicPath = dicPath
        self.content = content
        
    #형태소 & 개체명 분석  
    
    #자바 프로젝트에서 호출된 패키지 아래 존재하는 getNePosStream 클래스 호출
    def excute_analyzer_getNePosStream(self):
    	jpkg = jpype.JPackage('자바 프로젝트 패키지')
        getNePosStream = jpkg.getNePosStream()
        
        return getNePosStream
        
    def getNePos(self, excute_analyzer_getNePosStream):
    	#호출된 getNePosStream 클래스 아래 getNePos 함수 실행
    	getNePosStream = self.excute_analyzer_getNePosStream().getNePos(self.content)
        
        #getNePos는 HashMap을 반환한다. 그래서 추후에 python에서 사용하기 편하도록 Dictionary 형태로 변환
        NeAndPos = {}
        NeAndPos["Ne"] = getNePosStream["Ne"]
        NeAndPos["Pos"] = getNePosStream["Pos"]
        
        return NeAndPos
        
    #인용문 & 정보원 분석
    
    #자바 프로젝트에서 호출된 패키지 아래 존재하는 TextAnalyzer 클래스 호출
    def excute_analyzer_TextAnalyzer(self):
    	jpkg = jpype.JPackage('자바 프로젝트 패키지')
        oAnalyzer = jpkg.TextAnalyzer(self.dicPath, False, True, False)
        
        return oAnalyzer
        
    def textAnalyzer(self, excute_analyzer_TextAnalyzer):
    	jpkg2 = jpype.JPackage('자바 프로젝트 패키지2')
        #호출된 TextAnalyzer 클래스 아래 doAnalysis 등의 함수 실행
        analyzed_tms = self.excute_analyzer_TextAnalyzer().doAnalysis(jpkg2.Language.KOREAN, self.content, None, jpkg2.ArticleUpdate.all())
        
        if analyzed_tms.tagged is not None:
        	quotations = self.excute_analyzer_TextAnalyzer().getQuotations(analyzed_tms.tagged)
        else:
        	quotations = jpkg2.TextQuotation.EMPTY
            
        #추출된 quotations는 ArrayList 형식으로 반환되어 추후에 python에서 사용하기 편하도록 dictionary 형식으로 변환
        quotDict = {}
        for q in quotations:
        	quotDict[q.quotation] = q.source
            
        return quotDict

 

Test Package
from Analyzer import Analyzer
from Analyzer import JVM
# 형태소 & 개체명 분석 클래스 호출
def activeNePos(analyzer):

	getNePosStream = analyzer.excute_analyzer_getNePosStream()
    NePosDict = analyzer.getNePos(getNePosStream)
    print(NePosDict)
    
    return NePosDict
    
# 인용문 & 정보원 분석 클래스 호출
def activeQuote(analyzer):

	b = analyzer.excute_analyzer_TextAnalyzer()
    quotDict = analyzer.textAnalyzer(b)
    print(quotDict)
    
    return quotDict
def run(content):
	config = configparser.ConfigParser()
    ini_path = config_read('ini파일 경로' , encoding = 'utf-8')
    dataFile_path = config_.get("DIC_FILE_PATH', 'DATA_APTH')[1:-1]
    
    #Analyzer 객체 호출
    analyzer = Analyzer(dataFile_path, content)
    
    activeQuote(analyzer)
     OR
    activeQuote(analyzer)
if __name__ == "__main__":

	#JVM 구동
	JVM.startJVM
    
    #분석
    content = "content"
    run(content)

'솔트룩스 > 프로젝트' 카테고리의 다른 글

Project4 - Flask  (0) 2022.05.23
Project2 - ElasticSearch  (0) 2021.08.15
Project1_BeautifulSoup & Selenium VER2  (0) 2021.05.18
Project1_BeautifulSoup & Selenium VER1  (0) 2021.05.12