Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open office process connection timeout added #127

Merged
merged 1 commit into from
Feb 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@

/**
* A bootstrap connector which establishes a connection to an OOo server.
*
* <p>
* Most of the source code in this class has been taken from the Java class
* "Bootstrap.java" (Revision: 1.15) from the UDK projekt (Uno Software Develop-
* ment Kit) from OpenOffice.org (http:https://udk.openoffice.org/). The source code
* is available for example through a browser based online version control
* access at http:https://udk.openoffice.org/source/browse/udk/. The Java class
* "Bootstrap.java" is there available at
* http:https://udk.openoffice.org/source/browse/udk/javaunohelper/com/sun/star/comp/helper/Bootstrap.java?view=markup
*
* <p>
* The idea to develop this BootstrapConnector comes from the blog "Getting
* started with the OpenOffice.org API part III : starting OpenOffice.org with
* jars not in the OOo install dir by Wouter van Reeven"
Expand All @@ -49,54 +49,62 @@
*/
public class BootstrapConnector {

/** The OOo server. */
/**
* The OOo server.
*/
private OOServer oooServer;

/** The connection string which has ben used to establish the connection. */

/**
* The connection string which has ben used to establish the connection.
*/
private String oooConnectionString;

protected OfficeIntegration officeIntegration;

protected static final int CONNECTION_RETRY_INTERVAL = 500;

/**
* Constructs a bootstrap connector which connects to the specified
* OOo server.
*
* @param oooServer The OOo server
*
* @param oooServer The OOo server
*/
public BootstrapConnector(OOServer oooServer) {

public BootstrapConnector(OOServer oooServer, OfficeIntegration officeIntegration) {
this.oooServer = oooServer;
this.oooConnectionString = null;
this.officeIntegration = officeIntegration;
}

/**
* Connects to an OOo server using the specified accept option and
* connection string and returns a component context for using the
* connection to the OOo server.
*
* <p>
* The accept option and the connection string should match to get a
* connection. OOo provides to different types of connections:
* 1) The socket connection
* 2) The named pipe connection
*
* <p>
* To create a socket connection a host and port must be provided.
* For example using the host "localhost" and the port "8100" the
* accept option and connection string looks like this:
* - accept option : -accept=socket,host=localhost,port=8100;urp;
* - connection string: uno:socket,host=localhost,port=8100;urp;StarOffice.ComponentContext
*
* <p>
* To create a named pipe a pipe name must be provided. For example using
* the pipe name "oooPipe" the accept option and connection string looks
* like this:
* - accept option : -accept=pipe,name=oooPipe;urp;
* - connection string: uno:pipe,name=oooPipe;urp;StarOffice.ComponentContext
*
* @param oooConnectionString The connection string
* @return The component context
*
* @param oooConnectionString The connection string
* @return The component context
*/
public XComponentContext connect(String oooConnectionString) throws BootstrapException {

this.oooConnectionString = oooConnectionString;

XComponentContext xContext = null;
XComponentContext xContext;
try {
// get local context
XComponentContext xLocalContext = getLocalContext();
Expand All @@ -105,24 +113,26 @@ public XComponentContext connect(String oooConnectionString) throws BootstrapExc

// initial service manager
XMultiComponentFactory xLocalServiceManager = xLocalContext.getServiceManager();
if ( xLocalServiceManager == null )
if (xLocalServiceManager == null)
throw new BootstrapException("no initial service manager!");

// create a URL resolver
XUnoUrlResolver xUrlResolver = UnoUrlResolver.create(xLocalContext);

// wait until office is started
for (int i = 0;; ++i) {
long connectionTimeoutMillis = officeIntegration.getConnectionTimeoutSec() * 1000;
// wait until office is started but no longer than connectionTimeoutMillis
long start = System.currentTimeMillis();
for (; ; ) {
try {
xContext = getRemoteContext(xUrlResolver);
break;
} catch ( NoConnectException ex ) {
// Wait 500 ms, then try to connect again, but do not wait
// longer than 5 sec total:
if (i == 10) {
throw new BootstrapException(ex.toString());
} catch (NoConnectException ex) {
if (System.currentTimeMillis() - start < connectionTimeoutMillis) {
// Retry to connect after a short interval
Thread.sleep(CONNECTION_RETRY_INTERVAL);
} else {
throw new BootstrapException("Unable to connect to the OO process", ex);
}
Thread.sleep(500);
}
}
} catch (RuntimeException e) {
Expand All @@ -136,9 +146,9 @@ public XComponentContext connect(String oooConnectionString) throws BootstrapExc
/**
* Disconnects from an OOo server using the connection string from the
* previous connect.
*
* <p>
* If there has been no previous connect, the disconnects does nothing.
*
* <p>
* If there has been a previous connect, disconnect tries to terminate
* the OOo server and kills the OOo server process the connect started.
*/
Expand All @@ -159,11 +169,11 @@ public void disconnect() {
XComponentContext xRemoteContext = getRemoteContext(xUrlResolver);

// get desktop to terminate office
Object desktop = xRemoteContext.getServiceManager().createInstanceWithContext("com.sun.star.frame.Desktop",xRemoteContext);
Object desktop = xRemoteContext.getServiceManager().createInstanceWithContext(
"com.sun.star.frame.Desktop", xRemoteContext);
XDesktop xDesktop = (XDesktop) UnoRuntime.queryInterface(XDesktop.class, desktop);
xDesktop.terminate();
}
catch (Exception e) {
} catch (Exception e) {
// Bad luck, unable to terminate office
}

Expand All @@ -173,8 +183,8 @@ public void disconnect() {

/**
* Create default local component context.
*
* @return The default local component context
*
* @return The default local component context
*/
protected XComponentContext getLocalContext() throws BootstrapException, Exception {

Expand All @@ -187,10 +197,11 @@ protected XComponentContext getLocalContext() throws BootstrapException, Excepti

/**
* Try to connect to office.
*
* @return The remote component context
*
* @return The remote component context
*/
protected XComponentContext getRemoteContext(XUnoUrlResolver xUrlResolver) throws BootstrapException, ConnectionSetupException, IllegalArgumentException, NoConnectException {
protected XComponentContext getRemoteContext(XUnoUrlResolver xUrlResolver) throws BootstrapException,
ConnectionSetupException, IllegalArgumentException, NoConnectException {

Object context = xUrlResolver.resolve(oooConnectionString);
XComponentContext xContext = (XComponentContext) UnoRuntime.queryInterface(XComponentContext.class, context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ public class BootstrapSocketConnector extends BootstrapConnector {
*
* @param oooServer The OOo server
*/
public BootstrapSocketConnector(OOServer oooServer) {
super(oooServer);
public BootstrapSocketConnector(OOServer oooServer, OfficeIntegration officeIntegration) {
super(oooServer, officeIntegration);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public OfficeConnection(String openOfficePath, Integer port, ProcessManager proc
this.officeIntegration = officeIntegration;
this.oooServer = new OOServer(openOfficePath, OOServer.getDefaultOOoOptions(),
"localhost", port, processManager, officeIntegration);
this.bsc = new BootstrapSocketConnector(oooServer);
this.bsc = new BootstrapSocketConnector(oooServer, officeIntegration);
this.openOfficePath = openOfficePath;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class OfficeIntegration implements OfficeIntegrationAPI {
protected String temporaryDirPath;
protected Integer[] openOfficePorts;
protected Integer timeoutInSeconds = DEFAULT_TIMEOUT;
protected int connectionTimeoutSec = DEFAULT_CONNECTION_TIMEOUT;
protected int countOfRetry = DEFAULT_RETRY_COUNT;
protected int retryIntervalMs = DEFAULT_RETRY_INTERVAL;
protected Boolean displayDeviceAvailable = false;
Expand Down Expand Up @@ -74,6 +75,14 @@ public Integer getTimeoutInSeconds() {
return timeoutInSeconds;
}

public int getConnectionTimeoutSec() {
return connectionTimeoutSec;
}

public void setConnectionTimeoutSec(int connectionTimeoutSec) {
this.connectionTimeoutSec = connectionTimeoutSec;
}

public Boolean isDisplayDeviceAvailable() {
return displayDeviceAvailable;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public interface OfficeIntegrationAPI {
int DEFAULT_RETRY_COUNT = 2;
int DEFAULT_RETRY_INTERVAL = 1000;
int DEFAULT_TIMEOUT = 60;
int DEFAULT_CONNECTION_TIMEOUT = 15;

String getTemporaryDirPath();

Expand Down