From 7060c19665d7d22fbe15ab7bc43362555d25fb80 Mon Sep 17 00:00:00 2001 From: jangdongsin Date: Mon, 11 Nov 2024 10:25:54 +0900 Subject: [PATCH] =?UTF-8?q?mms=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=A0=84?= =?UTF-8?q?=EC=86=A1=20=EA=B7=9C=EA=B2=A9=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/server/packet/MmsMessage.java | 51 +++- .../munjaon/client/server/packet/Packet.java | 15 ++ .../server/service/CollectClientService.java | 239 +++++++++++++++--- 3 files changed, 266 insertions(+), 39 deletions(-) diff --git a/src/main/java/com/munjaon/client/server/packet/MmsMessage.java b/src/main/java/com/munjaon/client/server/packet/MmsMessage.java index a90c980..347213c 100644 --- a/src/main/java/com/munjaon/client/server/packet/MmsMessage.java +++ b/src/main/java/com/munjaon/client/server/packet/MmsMessage.java @@ -125,15 +125,62 @@ public final class MmsMessage { } ByteBuffer fileHeadBuffer = ByteBuffer.allocate(MmsMessage.DELIVER_MMS_FILENAME_LENGTH + MmsMessage.DELIVER_MMS_FILESIZE_LENGTH); fileHeadBuffer.put(DELIVER_MMS_FILENAME_POSITION, fileName.getBytes(Packet.AGENT_CHARACTER_SET)); - fileHeadBuffer.put(DELIVER_MMS_FILESIZE_POSITION, String.valueOf(file.length()).getBytes(Packet.AGENT_CHARACTER_SET)); + fileHeadBuffer.put(DELIVER_MMS_FILESIZE_POSITION, String.valueOf(file.length()).getBytes()); ByteBuffer fileBodyBuffer = ByteBuffer.allocate((int) file.length()); ByteBuffer fileBuffer = null; +// FileInputStream fis = null; try { +// fis = new FileInputStream(file); +// int bytesRead = 0; +// int position = 0; +// while ((bytesRead = fis.read()) != -1) { +// fileBodyBuffer.put(position++, (byte) bytesRead); +// } + +// System.out.println("Put Position = " + position); +// int read = fis.read(fileBodyBuffer.array()); +// System.out.println("Position = " + fileBodyBuffer.position() + " : Limit : " + fileBodyBuffer.limit()); fileBodyBuffer.put(Files.readAllBytes(file.toPath())); + System.out.println("Files.readAllBytes() = " + fileBodyBuffer.get(fileBodyBuffer.capacity() - 1)); fileBuffer = ByteBuffer.allocate(fileHeadBuffer.capacity() + fileBodyBuffer.capacity()); Packet.mergeBuffers(fileBuffer, fileHeadBuffer, fileBodyBuffer); - } catch (IOException e) {} + } catch (IOException e) { + } return fileBuffer; } + + public static ByteBuffer makeImageHeaderForDeliver(String path, String fileName) throws UnsupportedEncodingException { + if (path == null || fileName == null) { + return null; + } + File file = new File(path + fileName); + if (file.exists() == false) { + return null; + } + ByteBuffer fileHeadBuffer = ByteBuffer.allocate(MmsMessage.DELIVER_MMS_FILENAME_LENGTH + MmsMessage.DELIVER_MMS_FILESIZE_LENGTH); + fileHeadBuffer.put(DELIVER_MMS_FILENAME_POSITION, fileName.getBytes(Packet.AGENT_CHARACTER_SET)); + fileHeadBuffer.put(DELIVER_MMS_FILESIZE_POSITION, String.valueOf(file.length()).getBytes()); + + return fileHeadBuffer; + } + + public static ByteBuffer makeImageBodyForDeliver(String path, String fileName) throws UnsupportedEncodingException { + if (path == null || fileName == null) { + return null; + } + File file = new File(path + fileName); + if (file.exists() == false) { + return null; + } + + ByteBuffer fileBodyBuffer = null; + try { + fileBodyBuffer = ByteBuffer.allocate((int) file.length()); + fileBodyBuffer.put(Files.readAllBytes(file.toPath())); + } catch (IOException e) { + } + + return fileBodyBuffer; + } } diff --git a/src/main/java/com/munjaon/client/server/packet/Packet.java b/src/main/java/com/munjaon/client/server/packet/Packet.java index c8560c8..4245345 100644 --- a/src/main/java/com/munjaon/client/server/packet/Packet.java +++ b/src/main/java/com/munjaon/client/server/packet/Packet.java @@ -69,6 +69,21 @@ public final class Packet { // dest.put(srcHeadArray.length, srcBodyArray); } + public static void mergeBuffers(ByteBuffer dest, ByteBuffer[] srcArray) { + if (dest == null || srcArray == null || srcArray.length == 0) { + return; + } + + int destPosition = 0; + for (int i = 0; i < srcArray.length; i++) { + for (int j = 0; j < srcArray[i].capacity(); j++) { + dest.put(destPosition++, srcArray[i].get(j)); + System.out.println("i : " + i + " : j : " + j + " | byte : " + srcArray[i].get(j)); + } + System.out.println("destPosition : " + destPosition); + } + } + public static void printBuffer(ByteBuffer buffer) { if (buffer == null) { return; diff --git a/src/main/java/com/munjaon/client/server/service/CollectClientService.java b/src/main/java/com/munjaon/client/server/service/CollectClientService.java index 0c5435b..a90404e 100644 --- a/src/main/java/com/munjaon/client/server/service/CollectClientService.java +++ b/src/main/java/com/munjaon/client/server/service/CollectClientService.java @@ -4,6 +4,7 @@ import com.munjaon.client.model.MunjaonMsg; import com.munjaon.client.server.config.ErrorCode; import com.munjaon.client.server.packet.*; import com.munjaon.client.service.DatabaseTypeWorker; +import com.munjaon.client.util.ByteUtil; import com.munjaon.client.util.MessageCheckUtil; import com.munjaon.client.util.MessageUtil; import org.json.simple.JSONObject; @@ -12,7 +13,11 @@ import java.io.File; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; import java.nio.channels.SocketChannel; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.List; @@ -31,12 +36,16 @@ public class CollectClientService extends Service { private String pwd; // 접속 비밀번호 private List deliverList = null; + private boolean IS_ERROR = false; public CollectClientService(String serviceName, String serviceType) { super(serviceName); this.serviceType = serviceType; } + /** + * DBMS 테이블 생성여부 확인 + */ @Override public void checkReady() { worker = DatabaseTypeWorker.find(System.getProperty("DBMS")); @@ -62,9 +71,13 @@ public class CollectClientService extends Service { this.pwd = getProp("PASSWORD"); saveSystemLog("Try Connect to [ADDRESS : " + this.address + "] [PORT : " + this.port + "] [ID : " + this.id + "]"); try { + /* 클라이언트 소켓 오픈, nonblocking 모드 설정 */ socketChannel = SocketChannel.open(new InetSocketAddress(this.address, this.port)); socketChannel.configureBlocking(false); + /* 연결이 완료되었는지 체크 + * 3초간 서버와의 연결이 완료되었는지 체크 + * */ boolean isConnected = false; long connectStartTime = System.currentTimeMillis(); while (true) { @@ -88,6 +101,9 @@ public class CollectClientService extends Service { } } + /** + * socket 연결 해제 + */ @Override public void releaseResources() { if (socketChannel != null) { @@ -100,21 +116,29 @@ public class CollectClientService extends Service { } } + /** + * 패킷을 송수신한 마지막 시간 체크 + * @return + */ private boolean checkTimeOut() { return System.currentTimeMillis() - lastPacketSendTime >= Packet.LIMIT_PACKET_TIMEOUT; } @Override public void doService() { - bind(); + IS_ERROR = false; // 에러체크 초기화 + bind(); // 바이드 요청 while (isRun()) { + if (IS_ERROR) { + break; + } try { if (checkTimeOut()) { saveSystemLog("[checkTimeOut : Expired ... ... ... ... ... ... ...]"); break; }; - messageService(); - linkCheckService(); + messageService(); // 메시지 전송 처리 + linkCheckService(); // alive 체크 } catch (Exception e) { saveSystemLog("ERROR [" + e.getMessage() + "]"); saveSystemLog("ERROR DETAIL"); @@ -207,6 +231,7 @@ public class CollectClientService extends Service { } } } catch (Exception e) { + IS_ERROR = true; saveSystemLog("ERROR [" + e.getMessage() + "]"); saveSystemLog("ERROR DETAIL"); saveSystemLog(e.toString()); @@ -216,9 +241,10 @@ public class CollectClientService extends Service { worker.updateDeliverForList(this.deliverList); this.deliverList = null; // NULL로 초기화 } + } - private void smsMessageService(MunjaonMsg data) { + private void smsMessageService(MunjaonMsg data) throws Exception { try { /* 공통 메시지 유효성 체크 */ int checkCommonCode = MessageCheckUtil.validateMessageForCommon(data); @@ -252,12 +278,12 @@ public class CollectClientService extends Service { while (true) { if (System.currentTimeMillis() - MSG_SEND_TIME >= Packet.LIMIT_PACKET_SEND_TIMEOUT) { saveLog("[messageSendTimeOut : Expired ... ... ... ... ... ... ...]"); - throw new RuntimeException("messageSendTimeOut : Expired ... ... ... ... ... ... ..."); + throw new Exception("messageSendTimeOut : Expired ... ... ... ... ... ... ..."); } int recvCount = socketChannel.read(recvBuffer); if (recvCount == -1) { saveLog("[MESSAGE SEND] [FAIL] [SOCKET IS CLOSED]"); - throw new RuntimeException("DELIVER ERROR"); + throw new Exception("DELIVER ERROR"); } else if (recvCount > 0) { setDeliverMsgId(data.getMsgId()); // worker.updateToDeliver(data.getMsgId()); @@ -266,15 +292,15 @@ public class CollectClientService extends Service { break; } } - } catch (IOException e) { + } catch (Exception e) { saveSystemLog("ERROR [" + e.getMessage() + "]"); saveSystemLog("ERROR DETAIL"); saveSystemLog(e.toString()); - throw new RuntimeException(e); + throw new Exception(e); } } - private void lmsMessageService(MunjaonMsg data) { + private void lmsMessageService(MunjaonMsg data) throws Exception { try { /* 공통 메시지 유효성 체크 */ int checkCommonCode = MessageCheckUtil.validateMessageForCommon(data); @@ -308,12 +334,12 @@ public class CollectClientService extends Service { while (true) { if (System.currentTimeMillis() - MSG_SEND_TIME >= Packet.LIMIT_PACKET_SEND_TIMEOUT) { saveLog("[messageSendTimeOut : Expired ... ... ... ... ... ... ...]"); - throw new RuntimeException("messageSendTimeOut : Expired ... ... ... ... ... ... ..."); + throw new Exception("messageSendTimeOut : Expired ... ... ... ... ... ... ..."); } int recvCount = socketChannel.read(recvBuffer); if (recvCount == -1) { saveLog("[MESSAGE SEND] [FAIL] [SOCKET IS CLOSED]"); - throw new RuntimeException("DELIVER ERROR"); + throw new Exception("DELIVER ERROR"); } else if (recvCount > 0) { setDeliverMsgId(data.getMsgId()); // worker.updateToDeliver(data.getMsgId()); @@ -322,15 +348,141 @@ public class CollectClientService extends Service { break; } } - } catch (IOException e) { + } catch (Exception e) { saveSystemLog("ERROR [" + e.getMessage() + "]"); saveSystemLog("ERROR DETAIL"); saveSystemLog(e.toString()); - throw new RuntimeException(e); + throw new Exception(e); } } - private void mmsMessageService(MunjaonMsg data) { + private void mmsMessageService(MunjaonMsg data) throws Exception { + try { + /* 이미지 경로 디폴트 경로 사용 여부 */ + String defaultYn = getProp("MMS", "DEFAULT_PATH_YN"); + /* MMS Image 저장 경로 */ + String path = null; + if ("Y".equals(defaultYn)) { + path = System.getProperty("ROOTPATH") + File.separator + "mmsfile" + File.separator; + } else { + path = getProp("MMS", "FILEPATH") + File.separator; + } + + /* 공통 메시지 유효성 체크 */ + int checkCommonCode = MessageCheckUtil.validateMessageForCommon(data); + int checkMsgCode = MessageCheckUtil.validateMessageForMedia(data); + int checkImageCode = MessageCheckUtil.validateMessageForImage(data, path); + if (checkCommonCode != ErrorCode.OK.getCode() || checkMsgCode != ErrorCode.OK.getCode() || checkImageCode != ErrorCode.OK.getCode()) { + saveLog("[MESSAGE FILTER] [COMMON_CODE : " + checkCommonCode + "] [MSG_CODE : " + checkMsgCode + "] [IMAGE_CODE : " + checkImageCode + "]"); + saveLog("[MESSAGE DATA : " + data.toString() + "]"); + /* 전송처리 */ + worker.updateToDeliver(data.getMsgId()); + /* 실패처리 */ + MunjaonMsg errorMsg = null; + if (checkCommonCode != ErrorCode.OK.getCode()) { + errorMsg = MessageCheckUtil.setReportMessage(data.getMsgId(), "00", String.valueOf(checkCommonCode), MessageUtil.getTime(), "ETC"); + }else if (checkMsgCode != ErrorCode.OK.getCode()) { + errorMsg = MessageCheckUtil.setReportMessage(data.getMsgId(), "00", String.valueOf(checkMsgCode), MessageUtil.getTime(), "ETC"); + } else { + errorMsg = MessageCheckUtil.setReportMessage(data.getMsgId(), "00", String.valueOf(checkImageCode), MessageUtil.getTime(), "ETC"); + } + worker.updateToReport(errorMsg); + /* 처리완료 */ + return; + } + + /* 정상인 경우 메시지 전송 */ + ByteBuffer sendBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + MmsMessage.DELIVER_MMS_BODY_LENGTH); + ByteBuffer recvBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + MmsMessage.DELIVER_MMS_ACK_BODY_LENGTH); + int fileCount = 0; + /* File check */ + ByteBuffer file01HeadBuffer = MmsMessage.makeImageHeaderForDeliver(path, data.getFilename01()); + if (file01HeadBuffer != null) { + fileCount++; + } + ByteBuffer file02HeadBuffer = MmsMessage.makeImageHeaderForDeliver(path, data.getFilename02()); + if (file02HeadBuffer != null) { + fileCount++; + } + ByteBuffer file03HeadBuffer = MmsMessage.makeImageHeaderForDeliver(path, data.getFilename03()); + if (file03HeadBuffer != null) { + fileCount++; + } + + /* fileCount 저장 */ + data.setFileCount(fileCount); + + Header.putHeader(sendBuffer, Header.COMMAND_DELIVER, MmsMessage.DELIVER_MMS_BODY_LENGTH); + MmsMessage.makeDataForDeliver(sendBuffer, data); + saveLog("[MESSAGE SEND] [... ...]"); + saveLog("[MESSAGE DATA : " + data.toString() + "]"); + + int mmsBufferLength = sendBuffer.capacity(); + socketChannel.write(sendBuffer); + + if (file01HeadBuffer != null) { + socketChannel.write(file01HeadBuffer); + mmsImageSend(path + data.getFilename01()); + } + if (file02HeadBuffer != null) { + socketChannel.write(file02HeadBuffer); + mmsImageSend(path + data.getFilename02()); + } + if (file03HeadBuffer != null) { + socketChannel.write(file03HeadBuffer); + mmsImageSend(path + data.getFilename03()); + } + + long MSG_SEND_TIME = System.currentTimeMillis(); + while (true) { + if (System.currentTimeMillis() - MSG_SEND_TIME >= Packet.LIMIT_PACKET_SEND_TIMEOUT) { + saveLog("[messageSendTimeOut : Expired ... ... ... ... ... ... ...]"); + throw new Exception("messageSendTimeOut : Expired ... ... ... ... ... ... ..."); + } + int recvCount = socketChannel.read(recvBuffer); + if (recvCount == -1) { + saveLog("[MESSAGE SEND] [FAIL] [SOCKET IS CLOSED]"); + throw new Exception("DELIVER ERROR"); + } else if (recvCount > 0) { + setDeliverMsgId(data.getMsgId()); +// worker.updateToDeliver(data.getMsgId()); + saveLog("[MESSAGE SEND] [SUCCESS]"); + lastPacketSendTime = System.currentTimeMillis(); + break; + } + } + } catch (Exception e) { + e.printStackTrace(); + saveSystemLog("ERROR [" + e.getMessage() + "]"); + saveSystemLog("ERROR DETAIL"); + saveSystemLog(e.toString()); + throw new Exception(e); + } + } + + private void mmsImageSend(String imagePath) throws IOException { + ByteBuffer buff = ByteBuffer.allocate(1024); + Path src = Paths.get(imagePath); + + try (FileChannel rc = FileChannel.open(src, StandardOpenOption.READ)) { + int num; + while (true) { + num = rc.read(buff); + if (num == -1) { + break; + } + + buff.flip(); + socketChannel.write(buff); + buff.clear(); + } + + } catch (IOException e) { + throw e; + } + } + + private void mmsMessageService_bak(MunjaonMsg data) throws Exception { try { /* 이미지 경로 디폴트 경로 사용 여부 */ String defaultYn = getProp("MMS", "DEFAULT_PATH_YN"); @@ -373,22 +525,16 @@ public class CollectClientService extends Service { ByteBuffer file01Buffer = MmsMessage.makeImageForDeliver(path, data.getFilename01()); if (file01Buffer != null) { saveLog("file01Buffer : " + file01Buffer.capacity()); - } - if (file01Buffer != null) { fileCount++; } ByteBuffer file02Buffer = MmsMessage.makeImageForDeliver(path, data.getFilename02()); if (file02Buffer != null) { saveLog("file02Buffer : " + file02Buffer.capacity()); - } - if (file02Buffer != null) { fileCount++; } ByteBuffer file03Buffer = MmsMessage.makeImageForDeliver(path, data.getFilename03()); if (file03Buffer != null) { saveLog("file03Buffer : " + file03Buffer.capacity()); - } - if (file03Buffer != null) { fileCount++; } /* fileCount 저장 */ @@ -401,32 +547,50 @@ public class CollectClientService extends Service { ByteBuffer[] byteBuffers = new ByteBuffer[fileCount + 1]; int index = 0; + int mmsBufferLength = sendBuffer.capacity(); byteBuffers[index] = sendBuffer; + socketChannel.write(sendBuffer); index++; if (file01Buffer != null) { + System.out.println("file01Buffer Last = " + file01Buffer.get(file01Buffer.capacity() - 1)); + mmsBufferLength += file01Buffer.capacity(); byteBuffers[index] = file01Buffer; + socketChannel.write(file01Buffer); index++; } if (file02Buffer != null) { + System.out.println("file02Buffer Last = " + file02Buffer.get(file02Buffer.capacity() - 1)); + mmsBufferLength += file02Buffer.capacity(); byteBuffers[index] = file02Buffer; + socketChannel.write(file02Buffer); index++; } if (file03Buffer != null) { + System.out.println("file03Buffer Last = " + file03Buffer.get(file03Buffer.capacity() - 1)); + mmsBufferLength += file03Buffer.capacity(); byteBuffers[index] = file03Buffer; - index++; + socketChannel.write(file03Buffer); } - socketChannel.write(byteBuffers); + saveSystemLog("mmsBufferLength : " + mmsBufferLength); + saveSystemLog("byteBuffers : " + byteBuffers.length); + ByteBuffer mmsSendBuffer = ByteBuffer.allocate(mmsBufferLength); + Packet.mergeBuffers(mmsSendBuffer, byteBuffers); + + System.out.println("mmsSendBuffer Last = " + mmsSendBuffer.get(mmsSendBuffer.capacity() - 1)); + +// socketChannel.write(mmsSendBuffer); +// socketChannel.write(byteBuffers); long MSG_SEND_TIME = System.currentTimeMillis(); while (true) { if (System.currentTimeMillis() - MSG_SEND_TIME >= Packet.LIMIT_PACKET_SEND_TIMEOUT) { saveLog("[messageSendTimeOut : Expired ... ... ... ... ... ... ...]"); - throw new RuntimeException("messageSendTimeOut : Expired ... ... ... ... ... ... ..."); + throw new Exception("messageSendTimeOut : Expired ... ... ... ... ... ... ..."); } int recvCount = socketChannel.read(recvBuffer); if (recvCount == -1) { saveLog("[MESSAGE SEND] [FAIL] [SOCKET IS CLOSED]"); - throw new RuntimeException("DELIVER ERROR"); + throw new Exception("DELIVER ERROR"); } else if (recvCount > 0) { setDeliverMsgId(data.getMsgId()); // worker.updateToDeliver(data.getMsgId()); @@ -435,15 +599,16 @@ public class CollectClientService extends Service { break; } } - } catch (IOException e) { + } catch (Exception e) { + e.printStackTrace(); saveSystemLog("ERROR [" + e.getMessage() + "]"); saveSystemLog("ERROR DETAIL"); saveSystemLog(e.toString()); - throw new RuntimeException(e); + throw new Exception(e); } } - private void katMessageService(MunjaonMsg data) { + private void katMessageService(MunjaonMsg data) throws Exception { try { /* 이미지 경로 디폴트 경로 사용 여부 */ String defaultYn = getProp("KAKAO", "DEFAULT_PATH_YN"); @@ -498,12 +663,12 @@ public class CollectClientService extends Service { while (true) { if (System.currentTimeMillis() - MSG_SEND_TIME >= Packet.LIMIT_PACKET_SEND_TIMEOUT) { saveLog("[messageSendTimeOut : Expired ... ... ... ... ... ... ...]"); - throw new RuntimeException("messageSendTimeOut : Expired ... ... ... ... ... ... ..."); + throw new Exception("messageSendTimeOut : Expired ... ... ... ... ... ... ..."); } int recvCount = socketChannel.read(recvBuffer); if (recvCount == -1) { saveLog("[MESSAGE SEND] [FAIL] [SOCKET IS CLOSED]"); - throw new RuntimeException("DELIVER ERROR"); + throw new Exception("DELIVER ERROR"); } else if (recvCount > 0) { setDeliverMsgId(data.getMsgId()); // worker.updateToDeliver(data.getMsgId()); @@ -512,15 +677,15 @@ public class CollectClientService extends Service { break; } } - } catch (IOException e) { + } catch (Exception e) { saveSystemLog("ERROR [" + e.getMessage() + "]"); saveSystemLog("ERROR DETAIL"); saveSystemLog(e.toString()); - throw new RuntimeException(e); + throw new Exception(e); } } - private void kftMessageService(MunjaonMsg data) { + private void kftMessageService(MunjaonMsg data) throws Exception { try { /* 이미지 경로 디폴트 경로 사용 여부 */ String defaultYn = getProp("KAKAO", "DEFAULT_PATH_YN"); @@ -574,12 +739,12 @@ public class CollectClientService extends Service { while (true) { if (System.currentTimeMillis() - MSG_SEND_TIME >= Packet.LIMIT_PACKET_SEND_TIMEOUT) { saveLog("[messageSendTimeOut : Expired ... ... ... ... ... ... ...]"); - throw new RuntimeException("messageSendTimeOut : Expired ... ... ... ... ... ... ..."); + throw new Exception("messageSendTimeOut : Expired ... ... ... ... ... ... ..."); } int recvCount = socketChannel.read(recvBuffer); if (recvCount == -1) { saveLog("[MESSAGE SEND] [FAIL] [SOCKET IS CLOSED]"); - throw new RuntimeException("DELIVER ERROR"); + throw new Exception("DELIVER ERROR"); } else if (recvCount > 0) { setDeliverMsgId(data.getMsgId()); // worker.updateToDeliver(data.getMsgId()); @@ -588,11 +753,11 @@ public class CollectClientService extends Service { break; } } - } catch (IOException e) { + } catch (Exception e) { saveSystemLog("ERROR [" + e.getMessage() + "]"); saveSystemLog("ERROR DETAIL"); saveSystemLog(e.toString()); - throw new RuntimeException(e); + throw new Exception(e); } } @@ -622,10 +787,10 @@ public class CollectClientService extends Service { } } } catch (Exception e) { + IS_ERROR = true; saveSystemLog("ERROR [" + e.getMessage() + "]"); saveSystemLog("ERROR DETAIL"); saveSystemLog(e.toString()); - throw new RuntimeException(e); } }