12 Replies Latest reply on Apr 5, 2012 7:22 PM by morgalr

    How to execute certain method from new JVM?

    PavolAlcohol
      Hello

      I need to execute one method of certain class in another better new JVM.

      I found these ways how to run new JVM: ProcessBuilder or JavaTask(apache ant) but I think they execute main method of given class.

      Is this possible also without main method? The method I wish to execute in new JVM has parameter expecting instance of one my class(in memory) and I don't know how this could be passed through main method?

      Do you know some good tools for this?

      Any ideas?

      thanks
        • 1. Re: How to execute certain method from new JVM?
          gimbal2
          You start out with a technical solution; one that I would not choose unless I really had no other option at all.

          Why don't you take a step back and explain WHY you chose this solution and what you need to do exactly? Perhaps someone can give you some other options that are less... let me find a proper word... fragile.
          • 2. Re: How to execute certain method from new JVM?
            PavolAlcohol
            OK,

            Here is my concrete example. First, sorry for my english.

            I have implemented "ReportService" class generating the JasperReports (JasperPrint object) and export them to the pdf format for example. My service class can generate more than one report at once(via threads). As some reports can be very large cca 100MB(in memory) I decided to try to run each report in new JVM.

            So, my code to generate Jasper report is following:
            public void generateReport(String templatePath, String outFileName, Map paramMap, Connection connection)
            {
                 FileInputStream in = new FileInputStream(new File(templatePath));
                 
                 JasperReport jasperReport = (JasperReport) JRLoader.loadObject(in);
                 JasperPrint print = JasperFillManager.fillReport(jasperReport, paramMap, connection);
                 JasperExportManager.exportReportToPdfFile(print, outFileName);     
            }

            Now I need to execute this method in separate JVM.
            I could make it by new class and execute it in main method but I have got problems how to pass paramMap and connection through prameters in main method.

            I note that connection is achieved via connection pooler in ReportService class and I don't want to create it within new JVM. Same condition also for paramMap, it must me handled in service class.
            • 3. Re: How to execute certain method from new JVM?
              maheshguruswamy
              Metalpalo wrote:
              OK,

              Here is my concrete example. First, sorry for my english.

              I have implemented "ReportService" class generating the JasperReports (JasperPrint object) and export them to the pdf format for example. My service class can generate more than one report at once(via threads). As some reports can be very large cca 100MB(in memory) I decided to try to run each report in new JVM.

              So, my code to generate Jasper report is following:
              public void generateReport(String templatePath, String outFileName, Map paramMap, Connection connection)
              {
                   FileInputStream in = new FileInputStream(new File(templatePath));
                   
                   JasperReport jasperReport = (JasperReport) JRLoader.loadObject(in);
                   JasperPrint print = JasperFillManager.fillReport(jasperReport, paramMap, connection);
                   JasperExportManager.exportReportToPdfFile(print, outFileName);     
              }

              Now I need to execute this method in separate JVM.
              I could make it by new class and execute it in main method but I have got problems how to pass paramMap and connection through prameters in main method.

              I note that connection is achieved via connection pooler in ReportService class and I don't want to create it within new JVM. Same condition also for paramMap, it must me handled in service class.
              Hmm...looks like what you need is a queue. This queue can have logic to control how many reports get generated at the same time. The rest wait in the queue until all the tasks in the pipeline have completed.
              • 4. Re: How to execute certain method from new JVM?
                PavolAlcohol
                Maybe i could try use queue based on free memory, but what I want is to get a general solution how to run something like this above in separate JVM (process).
                • 5. Re: How to execute certain method from new JVM?
                  maheshguruswamy
                  Metalpalo wrote:
                  Maybe i could try use queue based on free memory, but what I want is to get a general solution how to run something like this above in separate JVM (process).
                  No, not based on memory. All you have to do is find how much average memory is consumed by one report and use a 'report count' to control how big your queue is. Spawing multiple JVM's is not that great a solution IMO.
                  • 6. Re: How to execute certain method from new JVM?
                    gimbal2
                    Metalpalo wrote:
                    Maybe i could try use queue based on free memory, but what I want is to get a general solution how to run something like this above in separate JVM (process).
                    But what would that solve? Either you generate 5 reports in one JVM and it uses 500mb (as an example) or you spawn 5 JVM instances and they each use 100mb, the total amount of memory used at one point is still the same (probably even more due to overhead), its just spread over multiple processes.

                    There is only one real solution to needing more memory: put more memory; which may require to just increase the maximum heap size or even installing more memory in the system. Not an unknown requirement in the reporting and analysis world anyway, generally that works on huge datasets and large volumes of memory are needed. In that respect, a couple of hundred megabytes is nothing.

                    That all is assuming that whatever tool you are using MUST do everything in memory of course; I can imagine that there is an option to just directly stream that stuff to a file on disc.
                    • 7. Re: How to execute certain method from new JVM?
                      PavolAlcohol
                      Either you generate 5 reports in one JVM and it uses 500mb (as an example) or you spawn 5 JVM instances and they each use 100mb, the total amount of memory >used at one point is still the same (probably even more due to overhead), its just spread over multiple processes.
                      I understand that here is still problem with memory, but again I wish to run in separate process.
                      • 8. Re: How to execute certain method from new JVM?
                        796440
                        Metalpalo wrote:
                        Either you generate 5 reports in one JVM and it uses 500mb (as an example) or you spawn 5 JVM instances and they each use 100mb, the total amount of memory >used at one point is still the same (probably even more due to overhead), its just spread over multiple processes.
                        I understand that here is still problem with memory, but again I wish to run in separate process.
                        Why? What benefit do you think you'll gain from adding this complexity?
                        • 9. Re: How to execute certain method from new JVM?
                          PavolAlcohol
                          Why? What benefit do you think you'll gain from adding this complexity?
                          Because it's better when just JVM(with one report) craches due to OutOfMemoryException than whole application generating five reports
                          • 10. Re: How to execute certain method from new JVM?
                            gimbal2
                            Metalpalo wrote:
                            Why? What benefit do you think you'll gain from adding this complexity?
                            Because it's better when just JVM(with one report) craches due to OutOfMemoryException than whole application generating five reports
                            Alright then, Its your choice. But that path does require spawning different processes; a method isn't a process, what you'll be spawning is a Java application running 5 times; you can use ProcessBuilder (or Runtime.exec()) to invoke the java command to execute the 5 processes, but you'll still need to design something that can actually execute as a standalone application to do the report generation. So yes, you need a class with a main() that does all the work. A possible interface to tell the application what to do could be simply passing command line parameters to the application.

                            This article is highly advised reading material before you make any attempt at implementing this:

                            http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html
                            • 11. Re: How to execute certain method from new JVM?
                              796440
                              Metalpalo wrote:
                              Why? What benefit do you think you'll gain from adding this complexity?
                              Because it's better when just JVM(with one report) craches due to OutOfMemoryException than whole application generating five reports
                              :headdesk:

                              * sigh * Okay, good luck.
                              • 12. Re: How to execute certain method from new JVM?
                                morgalr
                                Why not just generate each report to a file and do away with the memory reqirement?

                                I've had to deal with large datasets (Multi Gigabyte and now Terabytes) through my entire career and there is always a way to solve "out of memory" errors and it usually requires first stepping back and resolving that my process is not carved in stone, the programming gods will not be offended if I change my approach, and that the simplest solution may actually be best--or at least workable.

                                BTW: 500 Mb is not even a speedbump in my world.