Yarg problems with multithreading

Hello.
We have started to use Yarg library at our enterprise and have discovered some problems when two or more reports had runned. As a formatterFactory we use LibreOffice 5.
I’ve written a class with simple like example on your site and run it with next script:

   @Test
    void run(){
        int countJobs = 3;
        ExecutorService executorService = Executors.newFixedThreadPool(countJobs);
        ArrayList<Future<String>> result = new ArrayList<>();
        countJobs.times {result.add(executorService.submit(new YargReport()))}

        result.each {
            println(it.get())
        }
    }

Each time I get different result. Sometimes I don’t have errors, sometimes I have errors and have all results, sometimes a lot of errors and one result or only errors.

Error like:

java.util.concurrent.ExecutionException: java.lang.RuntimeException: com.haulmont.yarg.exception.OpenOfficeException: Unable to create Open office components.
Caused by: com.sun.star.uno.RuntimeException: socket,host=127.0.0.1,port=8101;urp already exists

With default factory all is ok.log.txt (58.6 KB)

Could you help with solution?

Nobody doesn’t have a solution ?

Hi,
Could you provide source code for YARG report? Or sample project with unit test and YARG report?

Thanks,
Andrey

Thanks for the answer

class YargReport implements Callable<String> {

    private static String TEMPLATE_PATH = "D:/dev/YargTemplates/"
    private static String language = "groovy";
    private String templateName = "zayavNaObsluzhivanieZarplatniyProektJRL_Middle.docx";
    private String formatName = "";
    private ReportFormatterFactory formatterFactory;
    ReportOutputType UserReportOutputType = ReportOutputType.pdf;

    public String doPrint(){
        ReportBuilder reportBuilder = new ReportBuilder();
        ReportTemplateBuilder reportTemplateBuilder = new ReportTemplateBuilder()
                .documentPath(TEMPLATE_PATH + templateName)
                .documentName(templateName)
                .outputType(UserReportOutputType)
                .readFileFromPath();
        reportBuilder.template(reportTemplateBuilder.build());
        Report report = reportBuilder.build();
        Reporting reporting = new Reporting();
      DefaultFormatterFactory formatterFactory = new DefaultFormatterFactory();
        OfficeIntegration officeIntegration = new OfficeIntegration("C:/Program Files/LibreOffice/program", 8101, 8102, 8103,8104,8105,8106,8107,8108,8109)
        formatterFactory.setOfficeIntegration(officeIntegration);
        reporting.setFormatterFactory(formatterFactory);
        reporting.setLoaderFactory(
                new DefaultLoaderFactory().setGroovyDataLoader(new GroovyDataLoader(new DefaultScriptingImpl())));
        ReportOutputDocument reportOutput = reporting.runReport(new RunParams(report));

        return new String( Base64Coder.encode(reportOutput.getContent()));
    }

    @Override
    String call() throws Exception {
        return doPrint();
    }
}

Hello. We have found workaround.
First of all, we moved formatterFactory from YargReport class and made its input parameter into the constructor.
It means that all object will have only one factory with office.

But that did not solve the problem. We marked method runTaskWithTimeout in OfficeIntegration class: synchronized. After that with 15 threads - all right.

Also LibreOffice threw some errors that parameters deprecated.
You should replace “-” on “–” Something like this:options.add("–nologo");

Hi,

You use OfficeIntegration for each thread. OfficeIntegration stores used ports and several instances of OfficeIntegration stores a separate list of used ports. So different threads may use same ports.
The better solution is to use Reporting with OfficeIntegration as a singleton.

Could you try to create Reporting with OfficeIntegration as a singleton and don’t mark runTaskWithTimeout as synchronized? Please attach new log file if the error occurs.

Thanks,
Andrey

Mytests.rar (90.8 KB)
Maybe I am doing something wrong, I am only junior but I have errors. But these errors are differents.
Could you show my log and classes?

Hi,

I have looked at the test project. You use only 3 ports for printing: 8101, 8102,8103, but you start 5 concurrent report execution, so exception ‘Couldn’t get free port from pool’ is in the log. An exception is correct because YARG tries to print report again. Could you try to increase ports count?
Also we have created YouTrack issue https://youtrack.cuba-platform.com/issue/YARG-55 because YARG uses only one LibreOffice for all ports. It causes exceptions with concurrent executions. This feature will fix the problem.

Thanks,
Andrey