JAVA : ERROR Java.util.prefs.WindowsPreferences.WindowsRegOp



我必须开发一个应用程序。此应用程序使用regedit保存首选项。此应用程序必须读取文件,如果文件不存在,则必须将其写入Regedit。一切都已经奏效了,这是一个已经存在的项目。我刚回去做一些Java 14测试我有这个错误

java.lang.NoSuchMethodException: java.util.prefs.WindowsPreferences.WindowsRegOpenKey(int,[B,int)
at java.base/java.lang.Class.getDeclaredMethod(Class.java:2553)
at com.myapp.application.WinRegistry.<clinit>(WinRegistry.java:62)
at com.myapp.application.XDeclicManager.plot(XDeclicManager.java:421)
at com.myapp.gui.XDeclicGUI$2.actionPerformed(XDeclicGUI.java:249)
at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308)
at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)

这是我的WinRegistry文件:

public class WinRegistry {

public static final int HKEY_CURRENT_USER  = 0x80000001;
public static final int HKEY_LOCAL_MACHINE = 0x80000002;
public static final int REG_SUCCESS        = 0;
public static final int REG_NOTFOUND       = 2;
public static final int REG_ACCESSDENIED   = 5;
private static final int KEY_ALL_ACCESS    = 0xf003f;
private static final int KEY_READ          = 0x20019;

private static Preferences userRoot = Preferences.userRoot();
private static Preferences systemRoot = Preferences.systemRoot();
private static Class<? extends Preferences> userClass = userRoot.getClass();

private static Method regOpenKey      = null;
private static Method regCloseKey     = null;
private static Method regQueryValueEx = null;
private static Method regEnumValue    = null;
private static Method regQueryInfoKey = null;
private static Method regEnumKeyEx    = null;
private static Method regCreateKeyEx  = null;
private static Method regSetValueEx   = null;
private static Method regDeleteKey    = null;
private static Method regDeleteValue  = null;
static {
try {
regOpenKey = userClass.getDeclaredMethod( "WindowsRegOpenKey", 
new Class[] { int.class, byte[].class, int.class });
regOpenKey.setAccessible(true);

regCloseKey = userClass.getDeclaredMethod( "WindowsRegCloseKey",
new Class[] { int.class });      
regCloseKey.setAccessible(true);

regQueryValueEx = userClass.getDeclaredMethod("WindowsRegQueryValueEx",
new Class[] { int.class, byte[].class });      
regQueryValueEx.setAccessible(true);

regEnumValue = userClass.getDeclaredMethod("WindowsRegEnumValue",
new Class[] { int.class, int.class, int.class });
regEnumValue.setAccessible(true);

regQueryInfoKey = userClass.getDeclaredMethod("WindowsRegQueryInfoKey1",
new Class[] { int.class });
regQueryInfoKey.setAccessible(true);

regEnumKeyEx = userClass.getDeclaredMethod( "WindowsRegEnumKeyEx", 
new Class[] { int.class, int.class, int.class });  
regEnumKeyEx.setAccessible(true);

regCreateKeyEx = userClass.getDeclaredMethod( "WindowsRegCreateKeyEx", 
new Class[] { int.class, byte[].class });  
regCreateKeyEx.setAccessible(true);

regSetValueEx = userClass.getDeclaredMethod( "WindowsRegSetValueEx", 
new Class[] { int.class, byte[].class, byte[].class });  
regSetValueEx.setAccessible(true);

regDeleteValue = userClass.getDeclaredMethod( "WindowsRegDeleteValue", 
new Class[] { int.class, byte[].class });  
regDeleteValue.setAccessible(true); 

regDeleteKey = userClass.getDeclaredMethod( "WindowsRegDeleteKey", 
new Class[] { int.class, byte[].class });  
regDeleteKey.setAccessible(true); 
}
catch (Exception e) {
e.printStackTrace();
}
}
private WinRegistry() {  }
/**
* Read a value from key and value name
* @param hkey   HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param key
* @param valueName
* @return the value
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static String readString(int hkey, String key, String valueName) 
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
{
if (hkey == HKEY_LOCAL_MACHINE) {
return readString(systemRoot, hkey, key, valueName);
}
else if (hkey == HKEY_CURRENT_USER) {
return readString(userRoot, hkey, key, valueName);
}
else {
throw new IllegalArgumentException("hkey=" + hkey);
}
}
/**
* Read value(s) and value name(s) form given key 
* @param hkey  HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param key
* @return the value name(s) plus the value(s)
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static Map<String, String> readStringValues(int hkey, String key) 
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
{
if (hkey == HKEY_LOCAL_MACHINE) {
return readStringValues(systemRoot, hkey, key);
}
else if (hkey == HKEY_CURRENT_USER) {
return readStringValues(userRoot, hkey, key);
}
else {
throw new IllegalArgumentException("hkey=" + hkey);
}
}
/**
* Read the value name(s) from a given key
* @param hkey  HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param key
* @return the value name(s)
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static List<String> readStringSubKeys(int hkey, String key) 
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
{
if (hkey == HKEY_LOCAL_MACHINE) {
return readStringSubKeys(systemRoot, hkey, key);
}
else if (hkey == HKEY_CURRENT_USER) {
return readStringSubKeys(userRoot, hkey, key);
}
else {
throw new IllegalArgumentException("hkey=" + hkey);
}
}
/**
* Create a key
* @param hkey  HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param key
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static void createKey(int hkey, String key) 
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
{
int [] ret;
if (hkey == HKEY_LOCAL_MACHINE) {
ret = createKey(systemRoot, hkey, key);
regCloseKey.invoke(systemRoot, new Object[] { new Integer(ret[0]) });
}
else if (hkey == HKEY_CURRENT_USER) {
ret = createKey(userRoot, hkey, key);
regCloseKey.invoke(userRoot, new Object[] { new Integer(ret[0]) });
}
else {
throw new IllegalArgumentException("hkey=" + hkey);
}
if (ret[1] != REG_SUCCESS) {
throw new IllegalArgumentException("rc=" + ret[1] + "  key=" + key);
}
}
/**
* Write a value in a given key/value name
* @param hkey
* @param key
* @param valueName
* @param value
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static void writeStringValue
(int hkey, String key, String valueName, String value) 
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
{
if (hkey == HKEY_LOCAL_MACHINE) {
writeStringValue(systemRoot, hkey, key, valueName, value);
}
else if (hkey == HKEY_CURRENT_USER) {
writeStringValue(userRoot, hkey, key, valueName, value);
}
else {
throw new IllegalArgumentException("hkey=" + hkey);
}
}
/**
* Delete a given key
* @param hkey
* @param key
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static void deleteKey(int hkey, String key) 
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
{
int rc = -1;
if (hkey == HKEY_LOCAL_MACHINE) {
rc = deleteKey(systemRoot, hkey, key);
}
else if (hkey == HKEY_CURRENT_USER) {
rc = deleteKey(userRoot, hkey, key);
}
if (rc != REG_SUCCESS) {
throw new IllegalArgumentException("rc=" + rc + "  key=" + key);
}
}
/**
* delete a value from a given key/value name
* @param hkey
* @param key
* @param value
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static void deleteValue(int hkey, String key, String value) 
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
{
int rc = -1;
if (hkey == HKEY_LOCAL_MACHINE) {
rc = deleteValue(systemRoot, hkey, key, value);
}
else if (hkey == HKEY_CURRENT_USER) {
rc = deleteValue(userRoot, hkey, key, value);
}
if (rc != REG_SUCCESS) {
throw new IllegalArgumentException("rc=" + rc + "  key=" + key + "  value=" + value);
}
}
// =====================
private static int deleteValue(Preferences root, int hkey, String key, String value)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
{
int[] handles = (int[]) regOpenKey.invoke( root, 
new Object[] {new Integer(hkey), toCstr(key), new Integer(KEY_ALL_ACCESS) });

if (handles[1] != REG_SUCCESS) {
return handles[1];                    // can be REG_NOTFOUND, REG_ACCESSDENIED
}

int rc =((Integer) regDeleteValue.invoke(root, 
new Object[] { new Integer(handles[0]), toCstr(value) })).intValue();
regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
return rc;
}

private static int deleteKey(Preferences root, int hkey, String key) 
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
{
int rc =((Integer) regDeleteKey.invoke(root,  
new Object[] { new Integer(hkey), toCstr(key) })).intValue();
return rc;  // can REG_NOTFOUND, REG_ACCESSDENIED, REG_SUCCESS
}

private static String readString(Preferences root, int hkey, String key, String value)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
{
int[] handles = (int[]) regOpenKey.invoke( root, 
new Object[] {new Integer(hkey), toCstr(key), new Integer(KEY_READ) });
if (handles[1] != REG_SUCCESS) {
return null; 
}

byte[] valb = (byte[]) regQueryValueEx.invoke( root, 
new Object[] {new Integer(handles[0]), toCstr(value) });

regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
return (valb != null ? new String(valb).trim() : null);
}

private static Map<String,String> readStringValues(Preferences root, int hkey, String key)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
{
HashMap<String, String> results = new HashMap<String,String>();
int[] handles = (int[]) regOpenKey.invoke( root, 
new Object[] {new Integer(hkey), toCstr(key), new Integer(KEY_READ) });
if (handles[1] != REG_SUCCESS) {
return null;
}

int[] info = (int[]) regQueryInfoKey.invoke( root, 
new Object[] { new Integer(handles[0]) });
int count  = info[0];   // count  
int maxlen = info[3];   // value length max

for(int index = 0; index < count; ++index)  {
byte[] name = (byte[]) regEnumValue.invoke( root, 
new Object[] {new Integer(handles[0]), new Integer(index), new Integer(maxlen + 1)});

String value = readString(hkey, key, new String(name));
results.put(new String(name).trim(), value);
}

regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
return results;
}
private static List<String> readStringSubKeys(Preferences root, int hkey, String key)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
{
List<String> results = new ArrayList<String>();
int[] handles = (int[]) regOpenKey.invoke( root, 
new Object[] {new Integer(hkey), toCstr(key), new Integer(KEY_READ)});

if (handles[1] != REG_SUCCESS) {
return null;
}

int[] info = (int[]) regQueryInfoKey.invoke( root,
new Object[] { new Integer(handles[0]) });
// Fix: info[2] was being used here with wrong results. 
// Suggested by davenpcj, confirmed by Petrucio
int count  = info[0];   
int maxlen = info[3];   // value length max

for( int index = 0; index < count; ++index)  {
byte[] name = (byte[]) regEnumKeyEx.invoke(root, 
new Object[] {new Integer(handles[0]), new Integer(index), new Integer(maxlen + 1)});
results.add(new String(name).trim());
}

regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
return results;
}
private static int [] createKey(Preferences root, int hkey, String key)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
{
return  (int[]) regCreateKeyEx.invoke(root,
new Object[] { new Integer(hkey), toCstr(key) });
}
private static void writeStringValue(Preferences root, int hkey, String key, String valueName, String value) 
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
{
int[] handles = (int[]) regOpenKey.invoke(root, 
new Object[] {new Integer(hkey), toCstr(key), new Integer(KEY_ALL_ACCESS) });
regSetValueEx.invoke(root,  
new Object[] {new Integer(handles[0]), toCstr(valueName), toCstr(value)}); 
regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
}
/*
*  utility method
*  convert String to byte array
*/
private static byte[] toCstr(String str) 
{
byte[] result = new byte[str.length() + 1];
for (int i = 0; i < str.length(); i++) {
result[i] = (byte) str.charAt(i);
}
result[str.length()] = 0;

return result;
}
}

我已经在regedit中创建了密钥:Software/JavaSoft/Prefs

有什么想法吗?谢谢:(

在Java 11中,WindowsPreferences中的句柄从int更改为long。此更改是在OpenJDK11中进行的。您必须更改方法签名才能使此代码在Java 11+环境中运行。例如:

regOpenKey = userClass.getDeclaredMethod( "WindowsRegOpenKey", 
new Class[] { int.class, byte[].class, int.class });

必须更改为:

regOpenKey = userClass.getDeclaredMethod( "WindowsRegOpenKey", 
new Class[] { long.class, byte[].class, int.class });

最新更新