I'm using LibreOffice 5.2 and I'm facing a strange error :
Here's my code :
Code: Select all
import com.sun.star.beans.PropertyValue;
import com.sun.star.bridge.UnoUrlResolver;
import com.sun.star.bridge.XUnoUrlResolver;
import com.sun.star.comp.helper.Bootstrap;
import com.sun.star.comp.helper.BootstrapException;
import com.sun.star.connection.NoConnectException;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.frame.XDesktop;
import com.sun.star.frame.XStorable;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.uno.XComponentContext;
import com.sun.star.util.CloseVetoException;
import com.sun.star.util.XCloseable;
import org.slf4j.Logger;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
import static com.google.common.base.Preconditions.*;
import static com.sun.star.comp.helper.Bootstrap.createInitialComponentContext;
import static com.sun.star.lib.util.NativeLibraryLoader.getResource;
import static com.sun.star.uno.UnoRuntime.queryInterface;
import static java.lang.String.format;
import static java.util.Arrays.stream;
import static java.util.regex.Pattern.compile;
import static java.util.stream.Collectors.joining;
import static org.slf4j.LoggerFactory.getLogger;
class OpenOfficeConnectionUnoImpl implements OpenOfficeConnection {
private static final Logger LOGGER = getLogger(OpenOfficeConnectionUnoImpl.class);
private static final String OFFICE_FILE_NAME = "soffice";
private static final String PIPE_NAME_MASK = NCProperties.getInstance().getProperty("pipe.name.mask", "uno_%s");
private static final String TMP_FOLDER_MASK = NCProperties.getInstance().getProperty("temp.folder.mask", "/tmp/openoffice_uno_%s");
private static final Pattern ID_PATTERN = compile("^[a-zA-Z0-9_-]+$");
private static final int CONNECTION_INTERVAL = 200;
private final String id;
private final long connectionTimeout;
private XComponentContext context;
private XDesktop desktop;
OpenOfficeConnectionUnoImpl(String id, long connectionTimeout) {
checkNotNull(id, "OpenOffice connection id is null");
checkArgument(ID_PATTERN.matcher(id).find(), "OpenOffice connection id is not valid");
checkArgument(connectionTimeout > CONNECTION_INTERVAL,
"OpenOffice connection timeout must be more than " + CONNECTION_INTERVAL);
this.id = id;
this.connectionTimeout = connectionTimeout;
}
@Override
public String getId() {
return id;
}
@Override
public void startConnection() throws Exception {
if (isAvailable()) return;
startOfficeInTerminal(id);
context = getXContext(id, connectionTimeout);
desktop = getXDesktop(context);
}
@Override
public boolean isStarted() {
return context != null && desktop != null;
}
@Override
public boolean isAvailable() {
if (!isStarted()) {
return false;
}
try {
return context.getServiceManager() != null;
} catch (Exception e) {
LOGGER.debug(format("OpenOffice connection '%s' is broken", id), e);
return false;
}
}
@Override
public void convertFile(String inputFilePath, String outputFilePath) throws Exception {
checkState(isAvailable(), "OpenOffice connection is not available");
XComponent document = getXDocument(desktop, inputFilePath);
performConvertFile(document, outputFilePath);
}
@Override
public void closeConnection() {
if (!isAvailable()) {
killOfficeInTerminal(id);
return;
}
try {
desktop.terminate();
} catch (Exception ignore) {
LOGGER.trace("Close OpenOffice desktop error", ignore);
}
closeUnoObject(context);
killOfficeInTerminal(id);
}
/**
* Create OpenOffice process in terminal with named pipe
*/
private void startOfficeInTerminal(String id) {
File fOffice = getResource(Bootstrap.class.getClassLoader(), OFFICE_FILE_NAME);
String defaultSofficeParams = "--headless --nologo --nodefault --norestore --nocrashreport --nolockcheck";
String sofficeParams = NCProperties.getInstance().getProperty("soffice.common.params", defaultSofficeParams);
List<String> sOfficeArgs = Arrays.asList(sofficeParams.trim().split(" "));
String defaultUnshareParams = "sudo unshare -n";
String unshareParams = NCProperties.getInstance().getProperty("unshare.common.params", defaultUnshareParams);
List<String> unshareArgs = Arrays.asList(unshareParams.trim().split(" "));
List<String> cmdArrayList = new ArrayList<>();
cmdArrayList.addAll(unshareArgs);
cmdArrayList.add(fOffice.getPath());
cmdArrayList.addAll(sOfficeArgs);
cmdArrayList.add("--accept=pipe,name=" + format(PIPE_NAME_MASK, id) + ";urp");
cmdArrayList.add("-env:UserInstallation=file://" + format(TMP_FOLDER_MASK, id) + "/");
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Start OpenOffice process: '{}'", cmdArrayList.stream().collect(joining(" ")));
}
ProcessBuilder processBuilder = new ProcessBuilder(cmdArrayList.toArray(new String[0]));
processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
processBuilder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
try {
processBuilder.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private XComponentContext getXContext(String id, long connectionTimeout) throws Exception {
XComponentContext xLocalContext = createInitialComponentContext(null);
XUnoUrlResolver xUrlResolver = UnoUrlResolver.create(xLocalContext);
String connectStr = "uno:pipe,name=" + format(PIPE_NAME_MASK, id) + ";urp;StarOffice.ComponentContext";
LOGGER.debug("Connect to OpenOffice process: '{}'", id);
LOGGER.debug("Connect String : '{}'", connectStr);
return getXComponentContext(xUrlResolver, connectStr, connectionTimeout);
}
private XComponentContext getXComponentContext(XUnoUrlResolver urlResolver, String connectStr, long timeout)
throws Exception {
long intervalCount = timeout / CONNECTION_INTERVAL;
for (int i = 0; ; ++i) {
LOGGER.trace(" i Count ------------------- : '{}'", i);
LOGGER.trace(" Interval Count ------------------- : '{}'", intervalCount);
try {
Object context = urlResolver.resolve(connectStr);
XComponentContext xContext = queryInterface(XComponentContext.class, context);
if (xContext == null) {
throw new BootstrapException("No OpenOffice component context");
} else {
return xContext;
}
} catch (NoConnectException e) {
// wait CONNECTION_INTERVAL ms, then try to connect again
// but do not wait longer then intervalCount times.
if (i == intervalCount) {
throw e;
}
Thread.sleep(CONNECTION_INTERVAL);
}
}
}
private XDesktop getXDesktop(XComponentContext context) throws Exception {
XMultiComponentFactory componentFactory = context.getServiceManager();
Object desktopService = componentFactory.createInstanceWithContext("com.sun.star.frame.Desktop", context);
return queryInterface(XDesktop.class, desktopService);
}
private XComponent getXDocument(XDesktop xDesktop, String path) throws Exception {
XComponentLoader xComponentLoader = queryInterface(XComponentLoader.class, xDesktop);
return xComponentLoader.loadComponentFromURL("file:///" + pathToUri(path), "_blank", 0, new PropertyValue[0]);
}
private void performConvertFile(XComponent document, String path) throws Exception {
XStorable xStorable = queryInterface(XStorable.class, document);
PropertyValue[] conversionProperties = new PropertyValue[1];
conversionProperties[0] = new PropertyValue();
conversionProperties[0].Name = "FilterName";
conversionProperties[0].Value = "writer_pdf_Export";
xStorable.storeToURL("file:///" + pathToUri(path), conversionProperties);
closeUnoObject(xStorable);
}
private String pathToUri(String path) {
return path.replace("\\", "/").replace("//", "/");
}
/**
* find and kill in terminal OpenOffice process with appropriate pipe name
*/
private void killOfficeInTerminal(String id) {
String[] killCmd = {
"/bin/sh", "-c",
"ps -ef | grep -E " +
"'" + OFFICE_FILE_NAME + "(.+)--accept=pipe,name=" + format(PIPE_NAME_MASK, id) + ";urp' " +
"| awk {'print $2'} | xargs kill -9"
};
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Kill OpenOffice process: '{}'", stream(killCmd).collect(joining(" ")));
}
try {
Runtime.getRuntime().exec(killCmd);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void closeUnoObject(Object obj) {
try {
XCloseable xCloseable = queryInterface(XCloseable.class, obj);
if (xCloseable != null) {
try {
xCloseable.close(false);
} catch (CloseVetoException e) {
throw new RuntimeException(e);
}
} else {
XComponent xComp = queryInterface(XComponent.class, obj);
if (xComp != null) {
xComp.dispose();
}
}
} catch (Exception ignore) {
LOGGER.trace("Close UNO object error", ignore);
}
}
@Override
public String toString() {
return "OpenOfficeConnectionUnoImpl{" +
"id='" + id + '\'' +
'}';
}
}
Exception :
Caused by: com.sun.star.connection.NoConnectException: java.io.IOException
at com.sun.star.lib.connections.pipe.pipeConnector.connect(pipeConnector.java:113)
at com.sun.star.comp.connections.Connector.connect(Connector.java:118)
at com.sun.star.comp.urlresolver.UrlResolver$_UrlResolver.resolve(UrlResolver.java:106)
at com.netcracker.solutions.gtdc.sfa.dg.converters.OpenOfficeConnectionUnoImpl.getXComponentContext(OpenOfficeConnectionUnoImpl.java:167)
at com.netcracker.solutions.gtdc.sfa.dg.converters.OpenOfficeConnectionUnoImpl.getXContext(OpenOfficeConnectionUnoImpl.java:159)
at com.netcracker.solutions.gtdc.sfa.dg.converters.OpenOfficeConnectionUnoImpl.startConnection(OpenOfficeConnectionUnoImpl.java:72)
at com.netcracker.solutions.gtdc.sfa.dg.converters.OpenOfficeConnectionFactory.makeObject(OpenOfficeConnectionFactory.java:49)
at com.netcracker.solutions.gtdc.sfa.dg.converters.OpenOfficeConnectionFactory.makeObject(OpenOfficeConnectionFactory.java:20)
Could anyone please help me or suggest with this ?
Thank you.
Using Oracle Linux 7.4