%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ page import="java.io.File" %>
<%@ page import="java.io.BufferedReader" %>
<%@ page import="java.io.InputStreamReader" %>
<%@ page import="java.lang.management.ManagementFactory" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page import="java.sql.SQLException" %>
<%@ page import="java.sql.Statement" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.LinkedHashMap" %>
<%@ page import="java.util.Map" %>
<%@ page import="javax.naming.InitialContext" %>
<%@ page import="javax.sql.DataSource" %>
<%@ page import="jakarta.servlet.ServletContext" %>
<%@ page import="javax.xml.parsers.DocumentBuilder" %>
<%@ page import="javax.xml.parsers.DocumentBuilderFactory" %>
<%@ page import="org.w3c.dom.Document" %>
<%!
private String html(Object value) {
if (value == null) return "";
String s = String.valueOf(value);
return s.replace("&", "&")
.replace("<", "<")
.replace(">", ">")
.replace(String.valueOf((char)34), """)
.replace("'", "'");
}
private String tag(String text, String type) {
String cls = "is-light";
if ("ok".equals(type)) cls = "is-success is-light";
else if ("warn".equals(type)) cls = "is-warning is-light";
else if ("error".equals(type)) cls = "is-danger is-light";
else if ("info".equals(type)) cls = "is-info is-light";
return "" + html(text) + " ";
}
private String formatBytes(long bytes) {
if (bytes < 0) return "-";
String[] units = {"B", "KB", "MB", "GB", "TB"};
double value = (double) bytes;
int idx = 0;
while (value >= 1024.0 && idx < units.length - 1) {
value = value / 1024.0;
idx++;
}
if (idx == 0) return String.valueOf(bytes) + " " + units[idx];
return String.format(java.util.Locale.GERMANY, "%.1f %s", value, units[idx]);
}
private String nullText(Object value) {
if (value == null || String.valueOf(value).length() == 0) {
return "nicht sichtbar / nicht gesetzt ";
}
return html(value);
}
private String jsString(Object value) {
if (value == null) return "";
String s = String.valueOf(value);
return s.replace("\\", "\\\\")
.replace("\r", "\\r")
.replace("\n", "\\n")
.replace("\t", "\\t")
.replace("\"", "\\\"");
}
private String joinPath(String base, String child) {
if (base == null || base.length() == 0) return null;
return new File(base, child).getPath();
}
private String fileCheckRow(String label, String path) {
StringBuilder sb = new StringBuilder();
sb.append("
").append(html(label)).append(" ");
if (path == null || path.length() == 0) {
sb.append("nicht ermittelbar ");
sb.append(" ").append(tag("unbekannt", "warn")).append(" ");
return sb.toString();
}
File f = new File(path);
sb.append("").append(html(path)).append(" ");
sb.append("");
sb.append(f.exists() ? tag("vorhanden", "ok") : tag("fehlt", "warn"));
sb.append(" ");
if (f.exists()) {
sb.append("lesbar: ").append(f.canRead() ? "ja" : "nein");
sb.append(", schreibbar: ").append(f.canWrite() ? "ja" : "nein");
if (f.isDirectory()) sb.append(", betretbar: ").append(f.canExecute() ? "ja" : "nein");
}
sb.append(" ");
return sb.toString();
}
private boolean tableExistsByRegclass(Connection con, String regclassName) {
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = con.prepareStatement("select to_regclass(?) is not null");
ps.setString(1, regclassName);
rs = ps.executeQuery();
return rs.next() && rs.getBoolean(1);
} catch (Exception e) {
return false;
} finally {
try { if (rs != null) rs.close(); } catch (Exception e) { }
try { if (ps != null) ps.close(); } catch (Exception e) { }
}
}
private boolean hasDbVersionTable(Connection con) {
return tableExistsByRegclass(con, "db_version") || tableExistsByRegclass(con, "public.db_version");
}
private Connection connectionFromObject(Object obj, boolean requireDbVersion) throws Exception {
if (!(obj instanceof DataSource)) return null;
Connection con = null;
try {
con = ((DataSource) obj).getConnection();
if (!requireDbVersion || hasDbVersionTable(con)) return con;
} catch (Exception e) {
try { if (con != null) con.close(); } catch (Exception ex) { }
throw e;
}
try { if (con != null) con.close(); } catch (Exception e) { }
return null;
}
private Object springBean(Object wac, String beanName) {
try {
java.lang.reflect.Method getBean = wac.getClass().getMethod("getBean", String.class);
return getBean.invoke(wac, beanName);
} catch (Exception e) {
return null;
}
}
private Connection connectionFromMap(Object obj, boolean requireDbVersion) throws Exception {
if (!(obj instanceof Map)) return null;
Map map = (Map) obj;
String[] preferredKeys = {"superx", "SuperX", "default", "hisinone", "eduetl"};
for (int i = 0; i < preferredKeys.length; i++) {
if (map.containsKey(preferredKeys[i])) {
Connection c = connectionFromObject(map.get(preferredKeys[i]), requireDbVersion);
if (c != null) return c;
}
}
for (Object value : map.values()) {
Connection c = connectionFromObject(value, requireDbVersion);
if (c != null) return c;
}
return null;
}
private Connection findSpringConnection(ServletContext application, boolean requireDbVersion) throws Exception {
Object wac = null;
try {
Class util = Class.forName("org.springframework.web.context.support.WebApplicationContextUtils");
java.lang.reflect.Method m = util.getMethod("getWebApplicationContext", ServletContext.class);
wac = m.invoke(null, application);
} catch (Exception e) {
wac = null;
}
if (wac == null) return null;
String[] beanNames = {"dataSources", "superxDataSource", "dataSource", "eduetlDataSource", "hisinoneDataSource"};
for (int i = 0; i < beanNames.length; i++) {
Object bean = springBean(wac, beanNames[i]);
Connection c = connectionFromMap(bean, requireDbVersion);
if (c != null) return c;
c = connectionFromObject(bean, requireDbVersion);
if (c != null) return c;
}
try {
java.lang.reflect.Method namesMethod = wac.getClass().getMethod("getBeanNamesForType", Class.class);
String[] names = (String[]) namesMethod.invoke(wac, DataSource.class);
if (names != null) {
for (int i = 0; i < names.length; i++) {
Object bean = springBean(wac, names[i]);
Connection c = connectionFromObject(bean, requireDbVersion);
if (c != null) return c;
}
}
} catch (Exception e) { }
return null;
}
private Connection findJndiConnection(boolean requireDbVersion) throws Exception {
String[] jndiNames = {
"java:comp/env/jdbc/superx",
"java:comp/env/jdbc/eduetl",
"java:comp/env/jdbc/hisinone",
"jdbc/superx",
"jdbc/eduetl",
"jdbc/hisinone"
};
InitialContext ctx = null;
try { ctx = new InitialContext(); } catch (Exception e) { ctx = null; }
if (ctx == null) return null;
for (int i = 0; i < jndiNames.length; i++) {
try {
Object obj = ctx.lookup(jndiNames[i]);
Connection c = connectionFromObject(obj, requireDbVersion);
if (c != null) return c;
} catch (Exception e) { }
}
return null;
}
private Connection findServletContextConnection(ServletContext application, boolean requireDbVersion) throws Exception {
String[] attrNames = {"dataSources", "dataSource", "datasource", "superxDataSource", "eduetlDataSource", "javax.sql.DataSource"};
for (int i = 0; i < attrNames.length; i++) {
try {
Object obj = application.getAttribute(attrNames[i]);
Connection c = connectionFromMap(obj, requireDbVersion);
if (c != null) return c;
c = connectionFromObject(obj, requireDbVersion);
if (c != null) return c;
} catch (Exception e) { }
}
return null;
}
private Connection openDiagnosticConnection(ServletContext application) throws Exception {
// Erste Runde: bevorzugt eine Verbindung, in der db_version sichtbar ist.
Connection c = findSpringConnection(application, true);
if (c != null) return c;
c = findJndiConnection(true);
if (c != null) return c;
c = findServletContextConnection(application, true);
if (c != null) return c;
// Zweite Runde: irgendeine verfügbare Verbindung, damit Diagnose nicht komplett ausfällt.
c = findSpringConnection(application, false);
if (c != null) return c;
c = findJndiConnection(false);
if (c != null) return c;
c = findServletContextConnection(application, false);
if (c != null) return c;
throw new SQLException("Keine DataSource über Spring, JNDI oder ServletContext gefunden. REST-Checks und Dateisystem-Checks bleiben trotzdem verfügbar.");
}
private String sqlColumnRows(Connection con, String tableSchema, String tableName) throws Exception {
PreparedStatement ps = null;
ResultSet rs = null;
StringBuilder sb = new StringBuilder();
try {
ps = con.prepareStatement("select column_name, data_type from information_schema.columns where table_schema = ? and table_name = ? order by ordinal_position");
ps.setString(1, tableSchema);
ps.setString(2, tableName);
rs = ps.executeQuery();
while (rs.next()) {
sb.append("").append(html(rs.getString(1))).append(" ").append(html(rs.getString(2))).append(" ");
}
} finally {
try { if (rs != null) rs.close(); } catch (Exception e) { }
try { if (ps != null) ps.close(); } catch (Exception e) { }
}
return sb.toString();
}
private String readTrimmedFile(File f) {
if (f == null || !f.exists() || !f.isFile() || !f.canRead()) return "";
StringBuilder sb = new StringBuilder();
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new java.io.FileInputStream(f), "UTF-8"));
String line;
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
} catch (Exception e) {
return "";
} finally {
try { if (br != null) br.close(); } catch (Exception e) { }
}
return sb.toString().trim();
}
private void disableXmlFeature(DocumentBuilderFactory factory, String feature) {
try { factory.setFeature(feature, false); } catch (Exception e) { }
}
private String readModuleXmlVersion(File xmlFile) {
if (xmlFile == null || !xmlFile.exists() || !xmlFile.isFile() || !xmlFile.canRead()) return "";
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false);
factory.setNamespaceAware(false);
disableXmlFeature(factory, "http://apache.org/xml/features/nonvalidating/load-external-dtd");
disableXmlFeature(factory, "http://xml.org/sax/features/external-general-entities");
disableXmlFeature(factory, "http://xml.org/sax/features/external-parameter-entities");
try { factory.setXIncludeAware(false); } catch (Exception e) { }
try { factory.setExpandEntityReferences(false); } catch (Exception e) { }
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(xmlFile);
if (doc != null && doc.getDocumentElement() != null) {
String version = doc.getDocumentElement().getAttribute("version");
if (version != null) return version.trim();
}
} catch (Exception e) {
return "";
}
return "";
}
private void addAvailableVersionInfo(Map map, String abbr, String xmlPath, String versionPath) {
if (abbr == null || abbr.trim().length() == 0) return;
String key = abbr.trim().toLowerCase();
Map info = new LinkedHashMap();
File xmlFile = xmlPath == null ? null : new File(xmlPath);
File versionFile = versionPath == null ? null : new File(versionPath);
String xmlVersion = readModuleXmlVersion(xmlFile);
String fileVersion = readTrimmedFile(versionFile);
info.put("xmlPath", xmlPath == null ? "" : xmlPath);
info.put("xmlVersion", xmlVersion == null ? "" : xmlVersion);
info.put("versionFilePath", versionPath == null ? "" : versionPath);
info.put("versionFileVersion", fileVersion == null ? "" : fileVersion);
if (xmlVersion != null && xmlVersion.length() > 0) {
info.put("version", xmlVersion);
info.put("source", "module_xml");
} else if (fileVersion != null && fileVersion.length() > 0) {
info.put("version", fileVersion);
info.put("source", "version_file");
} else {
info.put("version", "");
info.put("source", "");
}
map.put(key, info);
}
private String availableVersionJson(Map map) {
StringBuilder sb = new StringBuilder();
sb.append("{");
boolean first = true;
for (Object entryObj : map.entrySet()) {
Map.Entry entry = (Map.Entry) entryObj;
if (!first) sb.append(",");
first = false;
String key = String.valueOf(entry.getKey());
Map info = (Map) entry.getValue();
sb.append("\"").append(jsString(key)).append("\":{");
String[] props = {"version", "source", "xmlVersion", "xmlPath", "versionFileVersion", "versionFilePath"};
for (int i = 0; i < props.length; i++) {
if (i > 0) sb.append(",");
Object val = info.get(props[i]);
sb.append("\"").append(props[i]).append("\":\"").append(jsString(val == null ? "" : String.valueOf(val))).append("\"");
}
sb.append("}");
}
sb.append("}");
return sb.toString();
}
private String availableVersionRows(Map map) {
StringBuilder sb = new StringBuilder();
for (Object entryObj : map.entrySet()) {
Map.Entry entry = (Map.Entry) entryObj;
String key = String.valueOf(entry.getKey());
Map info = (Map) entry.getValue();
sb.append("").append(html(key)).append(" ");
sb.append("").append(info.get("xmlVersion") == null || String.valueOf(info.get("xmlVersion")).length() == 0 ? "nicht gefunden " : html(info.get("xmlVersion"))).append(" ");
sb.append("").append(html(info.get("xmlPath"))).append(" ");
sb.append("").append(info.get("versionFileVersion") == null || String.valueOf(info.get("versionFileVersion")).length() == 0 ? "nicht gefunden " : html(info.get("versionFileVersion"))).append(" ");
sb.append("").append(html(info.get("versionFilePath"))).append(" ");
sb.append("").append(info.get("version") == null || String.valueOf(info.get("version")).length() == 0 ? "nicht geliefert " : html(info.get("version"))).append(" ");
}
return sb.toString();
}
%>
<%
String diagGeneratedAt = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss").format(new Date());
String contextPath = request.getContextPath();
String servletRealPath = application.getRealPath("/");
String canonicalRealPath = "";
try { canonicalRealPath = servletRealPath == null ? "" : new File(servletRealPath).getCanonicalPath(); }
catch (Exception e) { canonicalRealPath = "nicht ermittelbar: " + e.getMessage(); }
String webInfPath = joinPath(servletRealPath, "WEB-INF");
String edustorePath = joinPath(webInfPath, "conf/edustore");
String dbPath = joinPath(edustorePath, "db");
String modulePath = joinPath(dbPath, "module");
String kernInstallPath = joinPath(dbPath, "install");
String kernXmlPath = joinPath(kernInstallPath, "conf/kern.xml");
String kernVersionFilePath = joinPath(kernInstallPath, "VERSION");
String kennPath = joinPath(modulePath, "kenn");
String kennXmlPath = joinPath(kennPath, "conf/kenn.xml");
String kennRohdatenPath = joinPath(kennPath, "rohdaten");
String kennSchluesselPath = joinPath(kennPath, "schluesseltabellen");
File diskBase = servletRealPath == null ? null : new File(servletRealPath);
long diskTotal = diskBase == null ? -1 : diskBase.getTotalSpace();
long diskFree = diskBase == null ? -1 : diskBase.getFreeSpace();
long diskUsable = diskBase == null ? -1 : diskBase.getUsableSpace();
boolean diskLow = diskUsable >= 0 && diskUsable < 1024L * 1024L * 1024L;
List jvmArgsList = ManagementFactory.getRuntimeMXBean().getInputArguments();
StringBuilder jvmArgsBuilder = new StringBuilder();
for (int i = 0; i < jvmArgsList.size(); i++) {
if (i > 0) jvmArgsBuilder.append(System.lineSeparator());
jvmArgsBuilder.append(String.valueOf(jvmArgsList.get(i)));
}
String jvmArgs = jvmArgsBuilder.toString();
boolean addOpensVisible = jvmArgs.indexOf("--add-opens=java.base/sun.net.www.protocol.jar=ALL-UNNAMED") >= 0;
String dbDiagnosticMessage = "";
String dbInfoHtml = "";
String jobLogTableTag = tag("unbekannt", "warn");
String jobLogColumnsHtml = "";
boolean dbDirectAvailable = false;
boolean jobLogExists = false;
boolean jobLogHasJobInstanceId = false;
boolean jobLogHasLog = false;
boolean jobLogHasStatus = false;
String dbVersionTableTag = tag("unbekannt", "warn");
String dbVersionRowsHtml = "";
String dbVersionFallbackJson = "{}";
String availableVersionFallbackJson = "{}";
String availableVersionRowsHtml = "";
Map availableVersionMap = new LinkedHashMap();
addAvailableVersionInfo(availableVersionMap, "kern", kernXmlPath, kernVersionFilePath);
if (modulePath != null) {
File moduleDir = new File(modulePath);
File[] moduleDirs = moduleDir.exists() && moduleDir.isDirectory() ? moduleDir.listFiles() : null;
if (moduleDirs != null) {
for (int i = 0; i < moduleDirs.length; i++) {
File md = moduleDirs[i];
if (md != null && md.isDirectory()) {
String abbr = md.getName();
if (!"kern".equalsIgnoreCase(abbr)) {
addAvailableVersionInfo(availableVersionMap, abbr, joinPath(md.getPath(), "conf/" + abbr + ".xml"), joinPath(md.getPath(), "VERSION"));
}
}
}
}
}
availableVersionFallbackJson = availableVersionJson(availableVersionMap);
availableVersionRowsHtml = availableVersionRows(availableVersionMap);
boolean dbVersionExists = false;
Connection diagCon = null;
try {
diagCon = openDiagnosticConnection(application);
dbDirectAvailable = true;
Statement st = null;
ResultSet rs = null;
try {
st = diagCon.createStatement();
rs = st.executeQuery("select current_database(), current_schema(), version()");
if (rs.next()) {
dbInfoHtml = "Datenbank " + html(rs.getString(1)) + " " +
"Schema " + html(rs.getString(2)) + " " +
"DB-Version " + html(rs.getString(3)) + " ";
}
} catch (Exception e) {
dbInfoHtml = "Direkte DB-Information " + tag("nicht verfügbar", "warn") + " " + html(e.getMessage()) + " ";
} finally {
try { if (rs != null) rs.close(); } catch (Exception e) { }
try { if (st != null) st.close(); } catch (Exception e) { }
}
PreparedStatement ps = null;
rs = null;
try {
ps = diagCon.prepareStatement("select to_regclass('public.job_log') is not null");
rs = ps.executeQuery();
if (rs.next()) jobLogExists = rs.getBoolean(1);
jobLogTableTag = jobLogExists ? tag("vorhanden", "ok") : tag("fehlt", "warn");
} catch (Exception e) {
jobLogTableTag = tag("Prüfung fehlgeschlagen", "warn") + " " + html(e.getMessage());
} finally {
try { if (rs != null) rs.close(); } catch (Exception e) { }
try { if (ps != null) ps.close(); } catch (Exception e) { }
}
if (jobLogExists) {
jobLogColumnsHtml = sqlColumnRows(diagCon, "public", "job_log");
ps = null;
rs = null;
try {
ps = diagCon.prepareStatement("select column_name from information_schema.columns where table_schema = 'public' and table_name = 'job_log'");
rs = ps.executeQuery();
while (rs.next()) {
String c = rs.getString(1);
if ("job_instance_id".equalsIgnoreCase(c)) jobLogHasJobInstanceId = true;
if ("log".equalsIgnoreCase(c)) jobLogHasLog = true;
if ("status".equalsIgnoreCase(c)) jobLogHasStatus = true;
}
} finally {
try { if (rs != null) rs.close(); } catch (Exception e) { }
try { if (ps != null) ps.close(); } catch (Exception e) { }
}
}
ps = null;
rs = null;
try {
ps = diagCon.prepareStatement("select (to_regclass('db_version') is not null or to_regclass('public.db_version') is not null)");
rs = ps.executeQuery();
if (rs.next()) dbVersionExists = rs.getBoolean(1);
dbVersionTableTag = dbVersionExists ? tag("vorhanden", "ok") : tag("fehlt", "warn");
} catch (Exception e) {
dbVersionTableTag = tag("Prüfung fehlgeschlagen", "warn") + " " + html(e.getMessage());
} finally {
try { if (rs != null) rs.close(); } catch (Exception e) { }
try { if (ps != null) ps.close(); } catch (Exception e) { }
}
if (dbVersionExists) {
ps = null;
rs = null;
StringBuilder versionJson = new StringBuilder();
boolean firstVersion = true;
versionJson.append("{");
try {
ps = diagCon.prepareStatement("select trim(his_system) as his_system, trim(version) as version, systeminfo_id from db_version order by his_system, systeminfo_id");
rs = ps.executeQuery();
while (rs.next()) {
String sys = rs.getString(1);
String ver = rs.getString(2);
Integer sid = null;
try { sid = (Integer) rs.getObject(3); } catch (Exception e) { sid = null; }
if (sys != null && ver != null && sys.trim().length() > 0 && ver.trim().length() > 0) {
String key = sys.trim().toLowerCase(java.util.Locale.ROOT);
if (!firstVersion) versionJson.append(",");
versionJson.append("\"").append(jsString(key)).append("\":\"").append(jsString(ver.trim())).append("\"");
firstVersion = false;
if (sid != null) {
versionJson.append(",\"sid:").append(sid.intValue()).append("\":\"").append(jsString(ver.trim())).append("\"");
}
dbVersionRowsHtml += "" + html(sys.trim()) + " " + html(ver.trim()) + " " + html(sid == null ? "" : sid) + " ";
}
}
} catch (Exception e) {
dbVersionRowsHtml = "" + tag("Prüfung fehlgeschlagen", "warn") + " " + html(e.getMessage()) + " ";
} finally {
try { if (rs != null) rs.close(); } catch (Exception e) { }
try { if (ps != null) ps.close(); } catch (Exception e) { }
}
versionJson.append("}");
dbVersionFallbackJson = versionJson.toString();
}
} catch (Exception e) {
dbDiagnosticMessage = e.getMessage();
dbInfoHtml = "Direkte DB-Prüfung " + tag("nicht verfügbar", "warn") + " " + html(e.getMessage()) + " ";
} finally {
try { if (diagCon != null) diagCon.close(); } catch (Exception e) { }
}
%>
SuperX Komponentenverwaltung
Alle Module Installiert Unload & Update möglich Unload möglich Update möglich DB verbunden DB nicht verbunden Aktualisieren Diagnose
Systemdiagnose Diagnose aktualisieren Schließen
Stand: <%= html(diagGeneratedAt) %>. Die Diagnose ändert nichts an Dateien oder Datenbankobjekten. SQL- und Shell-Befehle werden nur zum Kopieren angezeigt.
REST-Schnittstellen und aktuelle Oberfläche Noch nicht geprüft. Bitte Diagnose aktualisieren.
Versionen Noch nicht geprüft. Bitte Diagnose aktualisieren.
Verfügbare Versionen aus Modul-XML / VERSION-Dateien anzeigen Modul Modul-XML XML-Pfad VERSION-Datei VERSION-Pfad verwendbarer Fallback <%= availableVersionRowsHtml %>
Installierte Version: REST/JSON, sonst db_version. Verfügbare Version: REST/JSON, sonst version-Attribut der Modul-XML, sonst VERSION-Datei. Für kern wird db/install/conf/kern.xml verwendet.
Webapp / Tomcat / Java
Context Path <%= html(contextPath) %>
Servlet Real Path <%= html(servletRealPath) %>
Canonical Path <%= html(canonicalRealPath) %>
Server Info <%= html(application.getServerInfo()) %>
Java Version <%= html(System.getProperty("java.version")) %> / <%= html(System.getProperty("java.vendor")) %>
OS <%= html(System.getProperty("os.name")) %> <%= html(System.getProperty("os.version")) %> (<%= html(System.getProperty("os.arch")) %>)
user.name <%= html(System.getProperty("user.name")) %>
user.dir <%= html(System.getProperty("user.dir")) %>
catalina.base <%= html(System.getProperty("catalina.base")) %>
catalina.home <%= html(System.getProperty("catalina.home")) %>
JAVA_OPTS <%= nullText(System.getenv("JAVA_OPTS")) %>
CATALINA_OPTS <%= nullText(System.getenv("CATALINA_OPTS")) %>
JVM Input Arguments <%= html(jvmArgs) %>
Kettle/JarFileFactory add-opens <%= addOpensVisible ? tag("in JVM-Argumenten sichtbar", "ok") : tag("nicht sichtbar", "info") %>Nur Hinweis: relevant, wenn beim Laden/Ausführen der Jobs eine InaccessibleObjectException zu sun.net.www.protocol.jar auftritt.
Pfade und Dateisystem Prüfung Pfad Status Rechte
<%= fileCheckRow("WEB-INF", webInfPath) %><%= fileCheckRow("edustore", edustorePath) %><%= fileCheckRow("db", dbPath) %><%= fileCheckRow("db/install (Kernmodul)", kernInstallPath) %><%= fileCheckRow("db/install/conf/kern.xml", kernXmlPath) %><%= fileCheckRow("db/install/VERSION", kernVersionFilePath) %><%= fileCheckRow("module", modulePath) %><%= fileCheckRow("module/kenn", kennPath) %><%= fileCheckRow("kenn/conf/kenn.xml", kennXmlPath) %><%= fileCheckRow("kenn/rohdaten", kennRohdatenPath) %><%= fileCheckRow("kenn/schluesseltabellen", kennSchluesselPath) %>
Pfade werden nur angezeigt bzw. auf Existenz/Rechte geprüft. Aus dem Pfadnamen wird nicht automatisch abgeleitet, ob die Installation korrekt oder falsch ist. Besonderheit: Das Kernmodul wird unter db/install geprüft, nicht unter db/module/kern .
Festplattenspeicher Prüfpfad <%= html(servletRealPath) %> Gesamt <%= html(formatBytes(diskTotal)) %> Frei <%= html(formatBytes(diskFree)) %> Nutzbar für Tomcat-Prozess <%= html(formatBytes(diskUsable)) %> <%= diskLow ? tag("weniger als 1 GB", "warn") : tag("ok", "ok") %>
Datenbank / job_log <%= dbInfoHtml %>Direkte DB-Prüfung <%= dbDirectAvailable ? tag("verfügbar", "ok") : tag("nicht verfügbar", "warn") %><% if (!dbDirectAvailable) { %><%= html(dbDiagnosticMessage) %>
<% } %> Tabelle db_version <%= dbVersionTableTag %>Wird als Fallback für installierte Modulversionen verwendet, wenn /etl/list keine Version liefert.
Tabelle public.job_log <%= jobLogTableTag %> Spalte job_instance_id <%= jobLogHasJobInstanceId ? tag("vorhanden", "ok") : (jobLogExists ? tag("fehlt", "warn") : tag("nicht geprüft", "warn")) %> Spalte log <%= jobLogHasLog ? tag("vorhanden", "ok") : (jobLogExists ? tag("fehlt", "warn") : tag("nicht geprüft", "warn")) %> Spalte status <%= jobLogHasStatus ? tag("vorhanden", "ok") : (jobLogExists ? tag("fehlt / optional", "info") : tag("nicht geprüft", "warn")) %>
<% if (jobLogColumnsHtml != null && jobLogColumnsHtml.length() > 0) { %>Spalten von public.job_log anzeigen Spalte Datentyp <%= jobLogColumnsHtml %>
<% } %><% if (dbVersionRowsHtml != null && dbVersionRowsHtml.length() > 0) { %>Einträge aus public.db_version anzeigen his_system version systeminfo_id <%= dbVersionRowsHtml %>
<% } %>Hinweis: Wenn /ds/api/etl/jobLog/{id} HTTP 500 liefert, kann eine fehlende oder unvollständige Tabelle job_log eine mögliche Ursache sein.
SQL-Vorschlag: job_log anlegen Nur zum Kopieren. Die Diagnose führt diesen SQL nicht aus.
SQL kopieren
Bekannte Fehlerbilder und Hinweise /jobLog/{id} HTTP 500 Mögliche Ursachen: Tabelle job_log fehlt, Spalten fehlen, Logeintrag ist noch nicht geschrieben oder der Backend-Endpunkt fragt job_instance_id ab, während die Oberfläche eine JobExecutionId übergibt. /job/list/{modul} HTTP 500 Mögliche Ursachen: Moduldateien fehlen, Tomcat lädt eine andere Webapp als erwartet, alte Modulverzeichnisse liegen noch unter db/module oder JVM-Optionen für Kettle fehlen. /job/list/{modul} HTTP 404 Mögliche Ursachen: falscher Context-Pfad, falscher Port/Tunnel oder anderer Tomcat/Webapp-Kontext aktiv. Log lädt erst beim zweiten Klick Mögliche Ursachen: großer Logtext oder der Eintrag in job_log ist direkt nach COMPLETED noch nicht vollständig verfügbar.
Diese Hinweise sind bewusst vorsichtig formuliert. Sie nennen mögliche Ursachen, nicht zwingend die tatsächliche Ursache.
Shell-Hinweise für Administratoren Shell-Kommandos kopieren
Modul Status Versionen Letztes Update Datenquelle DB-Verbindung Aktionen Module werden geladen...
Aktueller Lauf Status aktualisieren Stoppen
JobExecutionId
-
Job
-
Status
Kein aktiver Lauf bekannt.
Fortschritt
Log-Ausgabe Noch kein Log geladen. Log laden Log leeren
Noch kein Lauf gestartet.