通过javascript杀死小程序

Killing applet through javascript

本文关键字:程序 javascript 通过      更新时间:2023-09-26

我创建了一个小程序,它需要执行以下代码:

代码

public class Example extends JApplet {
private ServerSocket ss ;
private Socket socket;
private boolean closed;
@Override
public void init(){
    try {
        new Example().initialize();
    } catch (IOException ex) {
        Logger.getLogger(Example.class.getName()).log(Level.SEVERE, null,ex);
    }
}
public void closed(){
    System.out.println("Inside close");
    this.closed=true;
  }
public void initialize() throws IOException{
    ss =new ServerSocket(5002);
    while(!closed){
    System.out.println("Waiting to accept request");
    socket = ss.accept();
    System.out.println("Request accepted");
    } 
}}

HTML

要执行小程序的HTML文件片段:

<script type="text/javascript" >  
 function closeCall(){  
 document.app.closed();  
 }  
 </script>  
   <body>  
<applet id="app" code="example.Example" archive="Example.jar" height="300" width="300">    
   </applet>  
   <input type="button" value="go" onClick="closeCall()" />  

问题:单击Go时,我的浏览器停止响应,javascript代码也没有错误。有什么方法可以调用document.app.closed();方法吗?

只有在将该代码转换为SSCCE后,许多问题才变得清晰起来:

  • 这段代码对我来说失败了,没有任何JS的迹象。这表明这与JS无关
  • 调用initialize()Example实例与小程序实例不同!UI是否检测到JS并不重要,它不会停止正在运行的实例
  • accept()正在阻止EDT
  • closed设置为true直到下一个客户端连接并且代码循环以再次检查closed属性的值之后才会生效。我通过调用ss.close()实现了这一点(这使得closed属性成为多余的BTW,但我保留了它)

BTW

  1. 请考虑将来发布SSCCE

代码

试试这个版本:

// <applet code='Example' width=400 height=100></applet>
import java.awt.event.*;
import javax.swing.*;
import java.net.*;
import java.io.*;
import java.util.logging.*;
public class Example extends JApplet {
    private ServerSocket ss ;
    private Socket socket;
    private boolean closed;
    @Override
    public void init(){
        JButton stop = new JButton("Stop!");
        stop.addActionListener( new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                closed();
            }
        });
        add( stop );
        validate();
        Runnable r = new Runnable() {
            public void run() {
                try {
                    initialize();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        };
        Thread t = new Thread(r);
        t.start();
    }
    public void closed() {
        System.out.println("Inside close");
        closed=true;
        try {
            ss.close();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    public void initialize() throws IOException {
        ss =new ServerSocket(5002);
        while(!closed){
            System.out.println("Waiting to accept request");
            socket = ss.accept();
            System.out.println("Request accepted");
        }
    }
}

Run

我在这个版本中添加了一个按钮,这样你就可以在没有JavaScript的情况下检查它是否按预期运行(在将JS放入混合之前,你应该用自己的代码检查一下)。AppletVewer使用源代码顶部的单行注释将代码放在屏幕上。这样使用:

prompt> appletviewer Example.java

典型输出

Waiting to accept request
Inside close
java.net.SocketException: socket closed
    at java.net.PlainSocketImpl.socketAccept(Native Method)
    at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
    at java.net.ServerSocket.implAccept(ServerSocket.java:462)
    at java.net.ServerSocket.accept(ServerSocket.java:430)
    at Example.initialize(Example.java:51)
    at Example$2.run(Example.java:27)
    at java.lang.Thread.run(Thread.java:662)
Tool completed successfully

我不相信applet安全沙箱允许您调用System#exit()。即使这样,也会对用户体验不利,因为如果不在浏览器中重新打开页面,最终用户将无法再次运行它。

相反,让while截取在close()方法中切换的boolean实例变量。例如

private boolean closed;
public void initialize() {
    while (!closed) {
        // ...
    }
}
public void close() {
    this.closed = true;
}

从pastebin.com尝试并通过javascript 杀死java小程序

<script>
 document.MyApplet.killApplet();
 </script>

 public void killApplet()
 {
    AccessController.doPrivileged(new PrivilegedAction()
   {
        public Void run() {
            // kill the JVM
            System.exit(0);
            return null;
        }
    });
 }