다음 문제를 이해하는 데 몇 가지 문제가 있습니다. 여기서는 말할 것도 없으므로 Runtime.exec() 메서드 호출에 바인딩 된 Process를 사용하여 Java 웹 응용 프로그램 내에서 실행되도록 외부 JAR을 작성해야했습니다. 이 외부 JAR은 데이터베이스 내에서 쿼리를 실행하고 그 결과를 Apache POI 라이브러리를 사용하여 Excel 파일에 인쇄합니다. 이이 코드입니다 : 아카이브 내부Runtime.exec()에서 프로그램을 실행할 때만 SQL 예외가 발생합니다.
public static void main(String[] args) {
//Initializing error variable
boolean error = false;
//Initializing rownum variable
int rownum = 0;
//Initializing db connection parameters
String userName = args[0];
String password = args[1];
String dbUrl = args[2];
//Initializing file path
String filePath = args[3];
//Initializing query string
String query = args[4];
if(!query.endsWith(";"))
query += ";";
//Keep 100 rows in memory, exceeding rows will be flushed to disk
SXSSFWorkbook wb = new SXSSFWorkbook(SXSSFWorkbook.DEFAULT_WINDOW_SIZE);
//Temp files will be gzipped
wb.setCompressTempFiles(true);
//Initializing xlsx sheet
Sheet sh = wb.createSheet();
wb.setSheetName(wb.getSheetIndex(sh), "DBExtraction");
//Trying to connect to db and execute a query.
//If the previous operation succeeded, parse query results
//into an xlsx workbook
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection conn = DriverManager.getConnection(dbUrl, userName, password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query);
ResultSetMetaData md = rs.getMetaData();
int cols = md.getColumnCount();
int cn = 0;
Row header = sh.createRow(rownum++);
for(int i = 0; i < cols; ++i) {
header.createCell(cn++).setCellValue(md.getColumnLabel(i + 1));
}
while(rs.next()) {
Row row = sh.createRow(rownum++);
cn = 0;
for (int cellnum = 0; cellnum < cols; cellnum++) {
Cell cell = row.createCell(cellnum);
cell.setCellValue(rs.getString(++cn));
}
}
for(int j = 0; j < cols; ++j) {
sh.setColumnWidth(j, 67*256);
}
FileOutputStream fos = new FileOutputStream(filePath);
//Writing workbook to file
wb.write(fos);
//Closing file
fos.flush();
fos.close();
//Dispose of temporary files backing this workbook on disk
wb.dispose();
wb.close();
//Closing db connection objects
rs.close();
stmt.close();
conn.close();
} catch (Exception e) {
error = true;
e.printStackTrace();
}
if(error)
System.exit(1);
else
System.exit(0);
}
또한 외부 라이브러리 (아파치 POI와 항아리 형식으로 SQL 서버 드라이버) 포장된다.
터미널 (cmd 또는 bash)에서 직접 프로그램을 실행하려고하면 java -jar executable.jar "param1" "param2" ...
명령을 사용하면 정상적으로 작동합니다.
위에서 언급 한 방법을 사용하여 동일한 명령을 실행하려고하면 문제가 발생합니다.
당신이 전화에 대한 책임의 코드를 발견 할 것이다 다음은
Process p = null;
p = Runtime.getRuntime().exec("java -jar " +
jarDir +
File.separator +
"executable.jar " +
"\"" + param0 + "\" " +
"\"" + param1 + "\" " +
"\"" + param2 + "\" " +
"\"" + param3 + "\" " +
"\"" + param4 +"\"");
p.waitFor();
String line;
BufferedReader error = new BufferedReader(new
InputStreamReader(p.getErrorStream()));
while((line = error.readLine()) != null){
System.out.println(line);
}
error.close();
BufferedReader input = new BufferedReader(new
InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
System.out.println(line);
}
input.close();
System.out.println("EXIT VALUE: " + p.exitValue());
을 두 번째 경우에, 나는 다음과 같은 예외를 얻을 : java.sql.SQLException: No suitable driver found for "jdbc:sqlserver://remoteServer:1433;databaseName=dbName"
.
웹 응용 프로그램은 현재 CentOS7 서버의 Wildfly 10.0.0-Final에서 실행됩니다.
감사합니다.
EDIT : JAR 매니페스트를 추가하는 것이 좋습니다. 몇 가지 실수가있을 수 있습니다 (JAR 파일은 Eclipse 내보내기에서 생성되었습니다) : MANIFEST.MF.
또한 JAR 내부 구조는 JAR Structure입니다.
를 @ esprittn 첫 번째 질문 : "이유는 다음과 같이 말할 수 없습니다."... – Fildor
@esprittn Erm, 나는 OP가 아닙니다. 다음 질문을주의 깊게 읽으십시오. "프로그램을 실행하려고하면 d 직접 터미널 (cmd 또는 bash)에서 ... " – Fildor
(가능한 경우) java -jar 대신 java -cp를 사용하려고 시도 했습니까? 그래서 당신은 classpath를 지정할 수 있고 jdbc 드라이버가 그것에 있는지를 확인할 수있다. 구문은 java -cp "[your classpath]"처럼 보입니다. [your.java.main] args .... –