问题
I'm trying to develop an applet in NetBeans which can read the MAC address.
So here is my directory structure
Here is my UPDATED Code
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;
};
When I try to run my applet from Run -> Run File
it works perfectly fine and shows my Mac address in it, with this log that I'm printing
Interfaces = en1;XX:XX:XX:XX:XX:XX
Interfaces JSON = ['en1;XX:XX:XX:XX:XX:XX']
But when I try to run it using
appletviewer build/MacAddrApplet.html
it prints
Interfaces = en1;
Interfaces JSON = ['en1;']
How can I solve this issue??
P.S. I think it's happening because it's not using the permissions of applet.policy
回答1:
Eventually I figured out what's wrong with the terminal command
appletviewer build/MacAddrApplet.html
because if you see the project.properties
file located in nbproject
folder, at the end part, you'll see
run.jvmargs=-Djava.security.policy=applet.policy
So when I run the applet using Run -> Run File
Netbeans internally took care of everything and hence the applet is running perfectly fine.
But, in case of the terminal, I need to specify the policy file
explicitly (This is what I want to know when I asked the question!), So run the applet with this command and it will work fine...
appletviewer -J-Djava.security.policy=applet.policy build/MacAddrApplet.html
回答2:
This is not necessarily a problem with Applet permissions. It's primarily a good old-fashioned bug in your code :-).
Read the docs for NetworkInterface.getHardwareAddress() - the method may 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")
You forgot the null check when calling it, thus the NullPointerException.
As to why you get back null
- that could be because of the SecurityManager (as the docs indicate), but in this case the problem is probably that InetAddress.getLocalHost()
gave you the localhost address, and consequently the interface you got is the loopback interface. The loopback interface, being a simulated interface, does not have a MAC address, so NetworkInterface.getHardwareAddress()
will return null
.
Taking a step backwards, your first mistake is to use InetAddress.getLocalHost()
. A computer can have multiple network interfaces, with multiple IP addresses (for example, a wired Ethernet interface and a WLAN interface, plus virtual interfaces such as loopback, or for a VPN client). So, in general, there is not "the MAC address", but 0-n MAC addresses, depending on system configuration.
You need to figure out how you choose your MAC address among those available. You can use NetworkInterface.getNetworkInterfaces()
to retrieve all interfaces the system has (even the deactivated ones), then go through them to decide which one you like (and which one has a MAC address).
来源:https://stackoverflow.com/questions/53080549/how-to-run-applet-with-policy-permissions-in-java-to-read-the-mac-address