Search code examples
javacompiler-errorsnativejnaloadlibrary

How do I rectify the Native.loadlibrary error


Here is my code. I have the JNA external jars imported, but I cannot compile this as I receive an error for "SPI INSTANCE = (SPI) Native.loadLibrary("user32", SPI.class, new HashMap() {". The error is: "The method loadLibrary(String, Class, Map) in the type Native is not applicable for the arguments (String, Class, new HashMap(){})"

package desktop;
import java.util.HashMap;

import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinDef.UINT_PTR;
import com.sun.jna.win32.*;

public class WallpaperChanger {
    public static void main(String[] args) {
        //supply your own path instead of using this one
        String path = "D:\\stone.png";

        SPI.INSTANCE.SystemParametersInfo(
            new UINT_PTR(SPI.SPI_SETDESKWALLPAPER), 
            new UINT_PTR(0), 
            path, 
            new UINT_PTR(SPI.SPIF_UPDATEINIFILE | SPI.SPIF_SENDWININICHANGE));
        }

        public interface SPI extends StdCallLibrary {

            //from MSDN article
            long SPI_SETDESKWALLPAPER = 20;
            long SPIF_UPDATEINIFILE = 0x01;
            long SPIF_SENDWININICHANGE = 0x02;

            @SuppressWarnings("serial")

            //This is where the error starts:
            SPI INSTANCE = (SPI) Native.loadLibrary("user32", SPI.class, new HashMap<Object, Object>() {
            {
                put(OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE);
                put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE);
            }
        });

        boolean SystemParametersInfo(
            UINT_PTR uiAction,
            UINT_PTR uiParam,
            String pvParam,
            UINT_PTR fWinIni
        );
    }
}

Solution

  • Try this:

        @SuppressWarnings("serial")
        SPI INSTANCE = (SPI) Native.loadLibrary("user32", SPI.class,
                new HashMap<String, Object>() {
                    {
                        put(OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE);
                        put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE);
                    }
                });
    

    The answer is quite simple, the method signature is com.sun.jna.Native#loadLibrary(java.lang.String, java.lang.Class<T>, java.util.Map<java.lang.String,?>).

    You have to pass java.util.Map<java.lang.String,?> instance rather than java.util.Map<java.lang.Object,java.lang.Object> instance.