0

I have Java swing application, and I want to run it from C#.

It works correctly when I use it from WindowsFormsApplication (see working version below). I set WindowsFormsApplication window invisible, and the application exits after I call System.exit(0); in Java. But when I try to run the same using ClassLibrary project, I cannot call Application.Run();, so the program exits immediately. (In debug mode using a breakpoint I can see that Java program with GUI initializes correctly and begins to run). How to make it wait until Java program exits?

Working example using WindowsFormsApplication:

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

using java.io;
using java.lang;
using java.util;
using net.sf.jni4net;
using net.sf.jni4net.adaptors;

using tt_factory;

namespace BookMap
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string [] args)
        {
            Init();
            TT_Factory.create_replay(); // creates Java GUI
            Application.Run();
        }

        private static void Init()
        {
            BridgeSetup bridgeSetup = new BridgeSetup(true);
            bridgeSetup.AddJVMOption("-Xms900m");
            bridgeSetup.AddAllJarsClassPath(Application.StartupPath + "\\..\\lib");
            bridgeSetup.JavaHome = Application.StartupPath + "\\..\\jre";
            Bridge.CreateJVM(bridgeSetup);
            Bridge.RegisterAssembly(typeof(TT_Factory).Assembly);
        }
    }
}

Example using ClassLibrary project and ConsoleApplication as test

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            BookMap.create_replay();
            /***** This method is implemented by ClassLibrary project:
             public static void create_replay() 
             {
                init_jvm();
                TT_Factory.create_replay();
             }
             ***** How to make program to wait here ? *****/
        }
    }
}

Update:

I tried starting new thread, but result is the same: the program exits immediately.

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread thread = new Thread(new ThreadStart(BookMap.create_replay));
            thread.Start();
            thread.Join();
        }
    }
}
Pavel Savara
  • 3,427
  • 1
  • 30
  • 35
Serg
  • 13,470
  • 8
  • 36
  • 47
  • Can you explain why you want to invoke an interactive program from something that isn't guaranteed to run in the context of a user? – M.Babcock Jan 09 '14 at 03:06
  • I have a whole GUI application, written in Java swing. Now I want to make it accessible from C# because some data sources required for the application have only C# API. But it's already working well with WindowsFormsApplication. I just can't make it running using ClassLibrary project. – Serg Jan 09 '14 at 03:11
  • Let's reword my question for clarity: You have an application that expects to run in a user-based context (someone logged onto the machine and will be looking at the pretty UI you expect to show) - you want to start said UI from a piece of code that doesn't know anything about showing a UI to the client --- why would you think this is a good thing? Yes this is possible (fairly simply actually) but rarely, if ever, makes sense. You haven't described the environment in which you expect said application to run so it's hard to guess why it is happening - just know it is a bad idea. – M.Babcock Jan 09 '14 at 03:18
  • I just want the C# program (ClassLibrary or ConsoleApplication) to run until Java is working. Exactly as it does using WindowsFormsApplication. I would be happy to explain what does the Java application and why I need an ability to run it using C#, but I think it might be off-topic or even considered as promotion. – Serg Jan 09 '14 at 03:26
  • That's not the question. When starting a UI from another UI you are guaranteed that the former UI is starting in an interactive user context. When starting a UI application from, say, a windows service, ASP.NET app, or other server oriented context; you may not have a user environment loaded. The specific context will drive how your application _needs_ to start the dependent app. – M.Babcock Jan 09 '14 at 03:37
  • @M.Babcock, The Java application starts as a most common swing application, i.e. in the EDT, and it works using WindowsFormsApplication. I just need to make it possible to start from any .NET or C++ environment (maybe ClassLibrary is not the right approach). If you have other ideas how to do that please advise. I'm ready to explain more details and pay for consultation (e.g. via oDesk) if you write me to "support at veloxpro dot com". Thanks. – Serg Jan 09 '14 at 12:14
  • 1
    @Serg Your .Net application should create an object to be notified when the Java UI has completed, and perform a WaitOne. When the Java code is completed, make a JNI call to a native windows DLL, loaded by your .Net application, which in turn will trigger Notify on the previously created object. The .Net application will then wake up, and terminate. – Samhain Jan 10 '14 at 20:49

1 Answers1

0

Here is a simple solution that works. I didn't understand yet how, but the program waits until Java application calls System.exit(0), and then exits regardless Console.Read();

From MSDN: The Read method blocks its return while you type input characters; it terminates when you press the Enter key.

In this case no one presses enter in the console.

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            BookMap.create_replay();
            Console.Read();
        }
    }
}
Serg
  • 13,470
  • 8
  • 36
  • 47