运行小程序如何在Java中使用策略权限读取MAC地址
How to run applet with policy permissions in Java to read the MAC address
我正在尝试在 NetBeans 中开发一个可以读取 MAC 地址的小程序。
这是我的目录结构
这是我的更新代码
MacAddrApplet.java
import java.awt.Graphics;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Enumeration;
import javax.swing.JApplet;
/**
*
* @author jay.patel
*/
public class MacAddressApplet extends JApplet {
public static String getMacFromInterface(NetworkInterface ni) throws SocketException {
byte mac[] = ni.getHardwareAddress();
if (mac != null) {
StringBuilder macAddress = new StringBuilder("");
String sep = "";
for (byte o : mac) {
macAddress.append(sep).append(String.format("%02X", o));
sep = ":";
}
return macAddress.toString();
}
return "";
}
public static String[] getInterfaces() {
try {
Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();
ArrayList<String> result = new ArrayList<String>();
while (nis.hasMoreElements()) {
NetworkInterface ni = nis.nextElement();
if (ni.isUp() && !ni.isLoopback() && !ni.isVirtual()) {
String mac = getMacFromInterface(ni);
String str = ni.getDisplayName() + ";" + mac;
result.add(str);
}
}
return result.toArray(new String[0]);
} catch (SocketException e) {
System.out.println("SocketException:: " + e.getMessage());
} catch (Exception e) {
System.out.println("Exception:: " + e.getMessage());
}
return new String[0];
}
public static String getInterfacesJSON() {
try {
String macs[] = getInterfaces();
String sep = "";
StringBuilder macArray = new StringBuilder("['");
for (String mac : macs) {
macArray.append(sep).append(mac);
sep = "','";
}
macArray.append("']");
return macArray.toString();
} catch (Exception e) {
System.out.println("Exception:: " + e.getMessage());
}
return "[]";
}
@Override
public void paint(Graphics g) {
super.paint(g);
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
String macs[] = getInterfaces();
for (String mac : macs) {
System.out.println(" Interfaces = " + mac);
}
System.out.println(" Interfaces JSON = " + getInterfacesJSON());
g.drawString("MAC: " + getInterfacesJSON(), 100, 100);
return null;
}
});
}
}
MacAddrApplet.html
<HTML>
<HEAD>
<TITLE>Applet HTML Page</TITLE>
</HEAD>
<BODY>
<H3><HR WIDTH="100%">Applet HTML Page<HR WIDTH="100%"></H3>
<P><APPLET codebase="classes" code="MacAddrApplet.class" width=350 height=200></APPLET></P>
<HR WIDTH="100%"><FONT SIZE=-1><I>Generated by NetBeans IDE</I></FONT>
</BODY>
applet.policy
grant {
permission java.security.AllPermission;
};
当我尝试从 Run -> Run File
运行 我的小程序时,它工作得很好,并在其中显示我的 Mac 地址,以及我正在打印的日志
Interfaces = en1;XX:XX:XX:XX:XX:XX
Interfaces JSON = ['en1;XX:XX:XX:XX:XX:XX']
但是当我尝试 运行 它使用
appletviewer build/MacAddrApplet.html
它打印
Interfaces = en1;
Interfaces JSON = ['en1;']
我该如何解决这个问题??
P.S。我认为它正在发生,因为它没有使用 applet.policy
的权限
这不一定是Applet权限的问题。这主要是您代码中的老式错误:-)。
阅读 NetworkInterface.getHardwareAddress()
的文档 - 方法可能 return null
:
returns: a byte array containing the address, or null if the address
doesn't exist, is not accessible or a security manager is set and the
caller does not have the permission
NetPermission("getNetworkInformation")
您在调用它时忘记了空检查,因此出现 NullPointerException。
至于 为什么 你回来 null
- 这可能是因为 SecurityManager(如文档所示),但在这种情况下,问题可能是InetAddress.getLocalHost()
给了你 localhost 地址,因此你得到的接口是环回接口。作为模拟接口的环回接口没有 MAC 地址,因此 NetworkInterface.getHardwareAddress()
将 return null
.
向后退一步,您的第一个错误是使用 InetAddress.getLocalHost()
。一台计算机可以有多个网络接口,有多个 IP 地址(例如,有线以太网接口和 WLAN 接口,加上环回等虚拟接口,或用于 VPN 客户端)。 所以,一般来说,不是"the MAC address",而是0-n个MAC地址,具体取决于系统配置。
您需要弄清楚如何在可用地址中选择 MAC 地址。您可以使用 NetworkInterface.getNetworkInterfaces()
检索系统拥有的所有接口(甚至是停用的接口),然后通过它们来决定您喜欢哪个(以及哪个具有 MAC 地址)。
最后我发现了终端命令有什么问题
appletviewer build/MacAddrApplet.html
因为如果您看到位于 nbproject
文件夹中的 project.properties
文件,在结尾部分,您会看到
run.jvmargs=-Djava.security.policy=applet.policy
所以当我 运行 使用 Run -> Run File
Netbeans 的小程序在内部处理了所有事情,因此小程序 运行 非常好。
但是,如果是终端,我需要明确指定policy file
(这是我问问题时想知道的!),所以 运行 使用此命令的小程序,它将正常工作...
appletviewer -J-Djava.security.policy=applet.policy build/MacAddrApplet.html
我正在尝试在 NetBeans 中开发一个可以读取 MAC 地址的小程序。
这是我的目录结构
这是我的更新代码
MacAddrApplet.java
import java.awt.Graphics;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Enumeration;
import javax.swing.JApplet;
/**
*
* @author jay.patel
*/
public class MacAddressApplet extends JApplet {
public static String getMacFromInterface(NetworkInterface ni) throws SocketException {
byte mac[] = ni.getHardwareAddress();
if (mac != null) {
StringBuilder macAddress = new StringBuilder("");
String sep = "";
for (byte o : mac) {
macAddress.append(sep).append(String.format("%02X", o));
sep = ":";
}
return macAddress.toString();
}
return "";
}
public static String[] getInterfaces() {
try {
Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();
ArrayList<String> result = new ArrayList<String>();
while (nis.hasMoreElements()) {
NetworkInterface ni = nis.nextElement();
if (ni.isUp() && !ni.isLoopback() && !ni.isVirtual()) {
String mac = getMacFromInterface(ni);
String str = ni.getDisplayName() + ";" + mac;
result.add(str);
}
}
return result.toArray(new String[0]);
} catch (SocketException e) {
System.out.println("SocketException:: " + e.getMessage());
} catch (Exception e) {
System.out.println("Exception:: " + e.getMessage());
}
return new String[0];
}
public static String getInterfacesJSON() {
try {
String macs[] = getInterfaces();
String sep = "";
StringBuilder macArray = new StringBuilder("['");
for (String mac : macs) {
macArray.append(sep).append(mac);
sep = "','";
}
macArray.append("']");
return macArray.toString();
} catch (Exception e) {
System.out.println("Exception:: " + e.getMessage());
}
return "[]";
}
@Override
public void paint(Graphics g) {
super.paint(g);
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
String macs[] = getInterfaces();
for (String mac : macs) {
System.out.println(" Interfaces = " + mac);
}
System.out.println(" Interfaces JSON = " + getInterfacesJSON());
g.drawString("MAC: " + getInterfacesJSON(), 100, 100);
return null;
}
});
}
}
MacAddrApplet.html
<HTML>
<HEAD>
<TITLE>Applet HTML Page</TITLE>
</HEAD>
<BODY>
<H3><HR WIDTH="100%">Applet HTML Page<HR WIDTH="100%"></H3>
<P><APPLET codebase="classes" code="MacAddrApplet.class" width=350 height=200></APPLET></P>
<HR WIDTH="100%"><FONT SIZE=-1><I>Generated by NetBeans IDE</I></FONT>
</BODY>
applet.policy
grant {
permission java.security.AllPermission;
};
当我尝试从 Run -> Run File
运行 我的小程序时,它工作得很好,并在其中显示我的 Mac 地址,以及我正在打印的日志
Interfaces = en1;XX:XX:XX:XX:XX:XX
Interfaces JSON = ['en1;XX:XX:XX:XX:XX:XX']
但是当我尝试 运行 它使用
appletviewer build/MacAddrApplet.html
它打印
Interfaces = en1;
Interfaces JSON = ['en1;']
我该如何解决这个问题??
P.S。我认为它正在发生,因为它没有使用 applet.policy
这不一定是Applet权限的问题。这主要是您代码中的老式错误:-)。
阅读 NetworkInterface.getHardwareAddress()
的文档 - 方法可能 return null
:
returns: a byte array containing the address, or null if the address doesn't exist, is not accessible or a security manager is set and the caller does not have the permission NetPermission("getNetworkInformation")
您在调用它时忘记了空检查,因此出现 NullPointerException。
至于 为什么 你回来 null
- 这可能是因为 SecurityManager(如文档所示),但在这种情况下,问题可能是InetAddress.getLocalHost()
给了你 localhost 地址,因此你得到的接口是环回接口。作为模拟接口的环回接口没有 MAC 地址,因此 NetworkInterface.getHardwareAddress()
将 return null
.
向后退一步,您的第一个错误是使用 InetAddress.getLocalHost()
。一台计算机可以有多个网络接口,有多个 IP 地址(例如,有线以太网接口和 WLAN 接口,加上环回等虚拟接口,或用于 VPN 客户端)。 所以,一般来说,不是"the MAC address",而是0-n个MAC地址,具体取决于系统配置。
您需要弄清楚如何在可用地址中选择 MAC 地址。您可以使用 NetworkInterface.getNetworkInterfaces()
检索系统拥有的所有接口(甚至是停用的接口),然后通过它们来决定您喜欢哪个(以及哪个具有 MAC 地址)。
最后我发现了终端命令有什么问题
appletviewer build/MacAddrApplet.html
因为如果您看到位于 nbproject
文件夹中的 project.properties
文件,在结尾部分,您会看到
run.jvmargs=-Djava.security.policy=applet.policy
所以当我 运行 使用 Run -> Run File
Netbeans 的小程序在内部处理了所有事情,因此小程序 运行 非常好。
但是,如果是终端,我需要明确指定policy file
(这是我问问题时想知道的!),所以 运行 使用此命令的小程序,它将正常工作...
appletviewer -J-Djava.security.policy=applet.policy build/MacAddrApplet.html