Java 在这种情况下,JVM或反射的新实例会有帮助吗

Java 在这种情况下,JVM或反射的新实例会有帮助吗,java,reflection,jvm,jframe,classloader,Java,Reflection,Jvm,Jframe,Classloader,我以前发布过一个问题,但没有得到明确的解决方案 因此,我发布了一个SSCCE,这可能有助于更好地理解所面临的问题 package myApp; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import javax.swing.JFrame; import App2.Applic2; public class MYApp { @SuppressWarni

我以前发布过一个问题,但没有得到明确的解决方案

因此,我发布了一个SSCCE,这可能有助于更好地理解所面临的问题

package myApp;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javax.swing.JFrame;

import App2.Applic2;

public class MYApp {

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static void main(String arg[]){
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setTitle("Application frame 1");
        f.setSize(200,200);
        f.setVisible(true);
        Class cls = Applic2.class;
        Object[] actuals = { new String[] { "" } };


        Method m = null;
        try {
            m=cls.getMethod("main", new Class[] { String[].class } );
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
            try {
                m.invoke(null,actuals);
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    }

}
第二包

package App2;

import javax.swing.JFrame;

public class Applic2  {

    @SuppressWarnings("unused")
    public static void main(String args[]){

        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(200,200);
        f.setVisible(true);
        f.setTitle("This needs not to be changed");
        NewFrame3 Frame3 = new  NewFrame3();
    }

}
App2包的第二类

package App2;

import javax.swing.JFrame;

public class NewFrame3 {

    public NewFrame3(){

        JFrame f = new JFrame();
            f.setTitle("f3");
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setSize(200,200);
            f.setLocation(200, 200);
            f.setVisible(true);
    }

}
MYAPP
调用
Applic2
的实例,后者进一步调用
NewFrame3
的实例。我们可以看到,如果我关闭'NewFrame3'的实例或
Applic2的实例,整个程序将关闭(由于
EXIT\u ON\u close
)语句

我想要一个解决方案,其中
MYAPP
不应在关闭
Applic2
NewFrame3
时关闭

我无法对APPlic2或NewFrame3进行任何更改。通过反射,如果我们试图将
EXIT\u ON\u CLOSE
打开
DISPOSE\u ON\u CLOSE
打开

在前面提到的另一个解决方案中,应该创建一个新的
JVM
实例,并且应该在这个新的
JVM
实例上的一个新进程中执行
Applic2
。但后来我发现runtime.exec接受Java命令作为输入,而不是像
method.invoke()
这样的Java语句

我可以通过加载Applic2的加载程序访问Applic2。我只能访问内存中Applic2的类文件,因此无法使用jar在runtime.exec()中运行。现在我该怎么解决呢

将这些语句添加到
MYApp
类中可确保在单击帧的关闭按钮时不会发生任何事情,但情况似乎并非如此

Frame[] f2 = JFrame.getFrames();

            for(Frame fx: f2){
                System.out.println(fx.getTitle());
                fx.addWindowListener(new WindowAdapter(){
                      public void windowClosing(WindowEvent we){


                      }
                      });

这段代码需要添加到实例化的最后一个帧中,否则它会返回所有帧。i、 例如,如果将此帧添加到JFrame3类中,则返回所有实例化的帧,如果将其添加到MyApp中,则返回MyApp中的JFrame;如果添加了Applic2,则返回MyApp和Applic2中实例化的帧。为什么会出现这种行为???

您可以使用
JFrame.getFrames()
返回
Frame
数组(您还可以
getWindows()
查看在当前应用程序上下文中创建的那些窗口的较低级别列表)

然后,您需要遍历,检查每个帧,看看它是否满足您的要求。之后,你不需要反射,你可以直接进入画面

与其他JVM通信的唯一方法是通过套接字通信(如RMI)

使用示例更新

Frame[] listOfFrames = JFrame.getFrames();
for (Frame : listOfFrames) {
  if (frame instanceof JFrame) {

      JFrame aFrame = (JFrame)frame;

  }
}

跨进程通信不是一件简单的事情。基本上,您想要与之交谈的每个进程都需要一个
ServerSocket
,它可以用它来接受传入的请求。如果要执行双向通信,每个进程都需要有自己的
ServerSocket
,这将允许任何进程启动通信

这会引起端口号等问题,但实际上您可以进行多播来克服这一问题(基本上是“大家好,我在这里,来和我谈谈”),这可以用来确定谁可用或不可用-请看一个示例

所以。准备好后,您将在相关进程(localhost/127.0.0.1)的端口上打开该进程的套接字连接并开始聊天

现在。我看到您所描述的问题是,为了让它运行,您需要某种启动器,它可以创建服务器套接字,然后执行现有的程序(如您所描述的),这就提出了一个问题:为什么?如果您的唯一目标是让这些帧停止关闭您的应用程序,那么只需在新的JVM中启动程序即可实现该目标。显然,如果你仍然需要他们提供更多的信息,那么这就是你努力工作的合理借口

现在,好消息是,您可以跨套接字序列化对象(也就是说,您可以通过套接字连接发送Java对象),查看更多信息

现在,如果这还没有吓跑你,请查看更多信息


最后,“如何”执行一个新JVM这个大问题,它实际上描述了一种执行新JVM的方法

在MadProgrammer和mKorbel提供的帮助下,我们完成了解决方案,下面是更新的MYApp类

package myApp;

import java.awt.Frame;
import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javax.swing.JFrame;

import App2.Applic2;

public class MYApp {

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static void main(String arg[]){
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setTitle("Application frame 1");
        f.setSize(200,200);
        f.setVisible(true);
        Class cls = Applic2.class;
        Object[] actuals = { new String[] { "" } };




        Method m = null;
        try {
            m=cls.getMethod("main", new Class[] { String[].class } );


            Method[] m1  =Frame.class.getDeclaredMethods();







        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
            try {
                m.invoke(null,actuals);
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }


            Frame[] f2 = JFrame.getFrames();
            //  Window[] f23=  JFrame.getFrames();

                for(Frame fx: f2){
                    System.out.println(fx.getTitle());
                    //  fx.setVisible(false);

                      if (fx instanceof JFrame) {

                          JFrame aFrame = (JFrame)fx;
                          aFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

                      }
                    }

    }

}

+1对于你的答案,这个解决方案似乎很有帮助,让我来实施它,并将答案贴在这里给你。但是,您可以建议如何使用新的JVM实例以另一种方式实现它。您是指其他JVM吗?您想与它对话(跨进程通信)还是执行它?是的,完全正确!!跨进程通信。执行应用程序的新进程但是getFrames()返回awt帧,如何更改这些帧的DefaultCloseOperation(awt帧没有任何这样的方法)JFrame从java.awt.frame扩展而来,您应该检查该帧是否是JFrame的实例,然后将其强制转换