von hardie82 » Do, 20.11.2008 08:56
Hallo Leute,
ich stehe seit Dienstag vor dem Problem, dass ich in einer Java-Spring-Webanwendung mehrere Dokumente gleichzeitig bearbeiten lassen muss. Wird die Anwendung von nur einem Client verwendet, funktioniert alles soweit ganz gut. Ich erstelle eine Verbindung, lasse mir das xDesktop-Objekt geben, öffne damit eine Templatedatei, bearbeite diese und speichere sie danach als PDF. Wenn ich während diesen Vorgang nun jedoch mit einem zweiten Client eine weitere Datei bearbeiten möchte erhalte ich auf dem ersten Client eine Nullpointer-Exception an einer Stelle wie "this.xText.setString(value);" und im zweiten Client eine "nested exception is com.sun.star.lang.DisposedException: java.io.IOException: com.sun.star.io.IOException: java.net.SocketException: Connection reset". Nun meine Frage: ist es mit open Office möglich, mehrere Dateien zeitgleich zu bearbeiten? An sich denke ich schon und vermute, dass das Problem bei meiner Implementierung liegt. Nur bin ich nicht genau dahinter gestiegen, wo der Fehler ist. Deshalb hier kurz mein Aufbau:
Datei 1: Klasse OConnection
Code: Alles auswählen
public class OConnection
{
private String ooExePath;
private Object xDesktop;
private XComponentContext xContext;
public void connect() throws Exception {
logger.debug("execute afterPropertiesSet");
try {
this.xContext = BootstrapSocketConnector.bootstrap(this.ooExePath);
XMultiComponentFactory xMCF = this.xContext.getServiceManager();
this.xDesktop = xMCF.createInstanceWithContext("com.sun.star.frame.Desktop", this.xContext);
}
catch(BootstrapException bse) {
logger.error("abort afterPropertiesSet -> " + bse.getMessage());
}
catch (Exception e) {
logger.error("abort afterPropertiesSet -> " + e.getMessage());
}
}
public void disconnect() throws Exception {
if(this.xDesktop != null) {
XDesktop desk = (XDesktop)UnoRuntime.queryInterface(XDesktop.class, this.xDesktop);
desk.terminate();
}
}
.... getter und setter
}
Klasse 2: Writer
Code: Alles auswählen
public class Writer
{
private OConnection oconnection;
private String tFilePath;
private XTextDocument ooDoc;
private XText xText;
private XNameAccess xNameBookmarks;
private Object bookmark;
private XTextTable xtable;
private XTextTablesSupplier xTSupplier;
private XComponentLoader xCLoader;
private XTextCursor xTextCursor;
private XPropertySet xTextCursProps;
public File[] createDocument(File source, Map<String, Object> resultList, String[] reporttypes, Locale language) {
try {
oconnection.connect();
this.xCLoader = (XComponentLoader)UnoRuntime.queryInterface(XComponentLoader.class, ooconnection.getXDesktop());
this.loadTemplate();
this.xTSupplier = (XTextTablesSupplier)UnoRuntime.queryInterface(XTextTablesSupplier.class, this.ooDoc);
this.getTextCursor();
...noch einiges andere
}
catch(...) {...}
this.closeDocument();
oconnection.disconnect();
}
private void loadTemplate() throws IOException, IllegalArgumentException {
String templateURL = "file:///" + tFilePath.replaceAll("\\\\", "/");
templateURL = ExternalUriReferenceTranslator.create(this.ooconnection.getXContext()).translateToExternal(templateURL);
//PropertieValues propVals setzen
this.ooDoc = (XTextDocument)UnoRuntime.queryInterface(XTextDocument.class,
this.xCLoader.loadComponentFromURL(templateURL, "_default", com.sun.star.frame.FrameSearchFlag.CHILDREN, propVals));
}
private void closeDocument() throws CloseVetoException {
XCloseable xcloseable = (XCloseable) UnoRuntime.queryInterface(XCloseable.class, this.ooDoc);
xcloseable.close(true);
}
Der Writer besitzt also ein Object der OConnection, welches über den Spring-Context erzeugt wird:
Code: Alles auswählen
<bean id="writer" class="de.myproject.domain.Writer">
<property name="oconnection" ref="oconnection" />
</bean>
<bean id="oconnection" class="de.myproject.domain.OConnection" singleton="false">
<property name="ooExePath" value="${ooExePath}" />
</bean>
Meine erste Vermutung war, dass die Connection ja nach jedem Bearbeiten wieder geschlossen wird und ich diese einfach als Singleton beim Start der Webanwendung iniziiere und beim Beenden der kompletten Anwendung die Connection erst wieder beende. Das hatte jedoch kein Effekt auf das Problem. Meine jetzige Vermutung ist, dass ich irgendein Objekt falsch benutze, sprich, dass ich ein Objekt durch den zweiten Client neu erzeuge und der erste dann nicht mehr darauf zugreifen kann. Hat da jemand eine Idee, woran das liegen könnte? Ich freue mich über jeden Hinweis. Und falls irgendetwas unklar ist, dann einfach fragen und ich versuche es dann näher zu erläutern.
Grüße
Hardie
Hallo Leute,
ich stehe seit Dienstag vor dem Problem, dass ich in einer Java-Spring-Webanwendung mehrere Dokumente gleichzeitig bearbeiten lassen muss. Wird die Anwendung von nur einem Client verwendet, funktioniert alles soweit ganz gut. Ich erstelle eine Verbindung, lasse mir das xDesktop-Objekt geben, öffne damit eine Templatedatei, bearbeite diese und speichere sie danach als PDF. Wenn ich während diesen Vorgang nun jedoch mit einem zweiten Client eine weitere Datei bearbeiten möchte erhalte ich auf dem ersten Client eine Nullpointer-Exception an einer Stelle wie "this.xText.setString(value);" und im zweiten Client eine "nested exception is com.sun.star.lang.DisposedException: java.io.IOException: com.sun.star.io.IOException: java.net.SocketException: Connection reset". Nun meine Frage: ist es mit open Office möglich, mehrere Dateien zeitgleich zu bearbeiten? An sich denke ich schon und vermute, dass das Problem bei meiner Implementierung liegt. Nur bin ich nicht genau dahinter gestiegen, wo der Fehler ist. Deshalb hier kurz mein Aufbau:
Datei 1: Klasse OConnection
[code]
public class OConnection
{
private String ooExePath;
private Object xDesktop;
private XComponentContext xContext;
public void connect() throws Exception {
logger.debug("execute afterPropertiesSet");
try {
this.xContext = BootstrapSocketConnector.bootstrap(this.ooExePath);
XMultiComponentFactory xMCF = this.xContext.getServiceManager();
this.xDesktop = xMCF.createInstanceWithContext("com.sun.star.frame.Desktop", this.xContext);
}
catch(BootstrapException bse) {
logger.error("abort afterPropertiesSet -> " + bse.getMessage());
}
catch (Exception e) {
logger.error("abort afterPropertiesSet -> " + e.getMessage());
}
}
public void disconnect() throws Exception {
if(this.xDesktop != null) {
XDesktop desk = (XDesktop)UnoRuntime.queryInterface(XDesktop.class, this.xDesktop);
desk.terminate();
}
}
.... getter und setter
}
[/code]
Klasse 2: Writer
[code]
public class Writer
{
private OConnection oconnection;
private String tFilePath;
private XTextDocument ooDoc;
private XText xText;
private XNameAccess xNameBookmarks;
private Object bookmark;
private XTextTable xtable;
private XTextTablesSupplier xTSupplier;
private XComponentLoader xCLoader;
private XTextCursor xTextCursor;
private XPropertySet xTextCursProps;
public File[] createDocument(File source, Map<String, Object> resultList, String[] reporttypes, Locale language) {
try {
oconnection.connect();
this.xCLoader = (XComponentLoader)UnoRuntime.queryInterface(XComponentLoader.class, ooconnection.getXDesktop());
this.loadTemplate();
this.xTSupplier = (XTextTablesSupplier)UnoRuntime.queryInterface(XTextTablesSupplier.class, this.ooDoc);
this.getTextCursor();
...noch einiges andere
}
catch(...) {...}
this.closeDocument();
oconnection.disconnect();
}
private void loadTemplate() throws IOException, IllegalArgumentException {
String templateURL = "file:///" + tFilePath.replaceAll("\\\\", "/");
templateURL = ExternalUriReferenceTranslator.create(this.ooconnection.getXContext()).translateToExternal(templateURL);
//PropertieValues propVals setzen
this.ooDoc = (XTextDocument)UnoRuntime.queryInterface(XTextDocument.class,
this.xCLoader.loadComponentFromURL(templateURL, "_default", com.sun.star.frame.FrameSearchFlag.CHILDREN, propVals));
}
private void closeDocument() throws CloseVetoException {
XCloseable xcloseable = (XCloseable) UnoRuntime.queryInterface(XCloseable.class, this.ooDoc);
xcloseable.close(true);
}
[/code]
Der Writer besitzt also ein Object der OConnection, welches über den Spring-Context erzeugt wird:
[code]
<bean id="writer" class="de.myproject.domain.Writer">
<property name="oconnection" ref="oconnection" />
</bean>
<bean id="oconnection" class="de.myproject.domain.OConnection" singleton="false">
<property name="ooExePath" value="${ooExePath}" />
</bean>
[/code]
Meine erste Vermutung war, dass die Connection ja nach jedem Bearbeiten wieder geschlossen wird und ich diese einfach als Singleton beim Start der Webanwendung iniziiere und beim Beenden der kompletten Anwendung die Connection erst wieder beende. Das hatte jedoch kein Effekt auf das Problem. Meine jetzige Vermutung ist, dass ich irgendein Objekt falsch benutze, sprich, dass ich ein Objekt durch den zweiten Client neu erzeuge und der erste dann nicht mehr darauf zugreifen kann. Hat da jemand eine Idee, woran das liegen könnte? Ich freue mich über jeden Hinweis. Und falls irgendetwas unklar ist, dann einfach fragen und ich versuche es dann näher zu erläutern.
Grüße
Hardie