Skip to content

java.lang.IllegalStateException: Pointer native already mapped to Proxy interface to native function #326

@hakanai

Description

@hakanai

I get an exception when I attempt to upgrade to JNA 4.1:

Exception in thread "main" java.lang.ExceptionInInitializerError
    at com.nuix.JnaExceptionTest.main(JnaExceptionTest.java:13)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: java.lang.IllegalStateException: Pointer native@0x7fff917299d0 already mapped to Proxy interface to native function@0x7fff917299d0 (com.nuix.JnaExceptionTest$CFDictionaryKeyCallBacks$PlaceholderCallback)
    at com.sun.jna.CallbackReference.getCallback(CallbackReference.java:122)
    at com.sun.jna.CallbackReference.getCallback(CallbackReference.java:105)
    at com.sun.jna.Pointer.getValue(Pointer.java:430)
    at com.sun.jna.Structure.readField(Structure.java:669)
    at com.sun.jna.Structure.read(Structure.java:537)
    at com.nuix.JnaExceptionTest$CFDictionaryValueCallBacks.<init>(JnaExceptionTest.java:105)
    at com.nuix.JnaExceptionTest$CFDictionaryValueCallBacks.<clinit>(JnaExceptionTest.java:90)
    ... 6 more

I have narrowed the issue down to a few classes and removed the bits which are not necessary to reproduce the issue:

import com.sun.jna.*;
import com.sun.jna.win32.StdCallFunctionMapper;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JnaExceptionTest {
    public static void main(String[] args) {
        new CFDictionaryValueCallBacks();
    }

    public static interface CoreFoundation extends Library {

        Map<Object, Object> defaultOptions = new HashMap<Object, Object>() {{
            put(Library.OPTION_FUNCTION_MAPPER, new StdCallFunctionMapper());
        }};

        public static final NativeLibrary JNA_NATIVE_LIB = NativeLibrary.getInstance("CoreFoundation", defaultOptions);
        public static final CoreFoundation INSTANCE = (CoreFoundation)
            Native.loadLibrary("CoreFoundation", CoreFoundation.class, defaultOptions);

        CFMutableDictionary CFDictionaryCreateMutable(CFAllocator allocator, NativeLong capacity,
                                                      CFDictionaryKeyCallBacks keyCallBacks,
                                                      CFDictionaryValueCallBacks valueCallBacks);

    }

    public static class CFMutableDictionary extends PointerType {
        public CFMutableDictionary() {
        }

        public CFMutableDictionary(Pointer pointer) {
            super(pointer);
        }
    }

    public static class CFAllocator extends PointerType {
        public CFAllocator() {
        }

        public CFAllocator(Pointer pointer) {
            super(pointer);
        }
    }

    public static class CFDictionaryKeyCallBacks extends Structure {
        public static final CFDictionaryKeyCallBacks kCFCopyStringDictionaryKeyCallBacks = new CFDictionaryKeyCallBacks(
            CoreFoundation.JNA_NATIVE_LIB.getGlobalVariableAddress("kCFCopyStringDictionaryKeyCallBacks"));

        public static final CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks = new CFDictionaryKeyCallBacks(
            CoreFoundation.JNA_NATIVE_LIB.getGlobalVariableAddress("kCFTypeDictionaryKeyCallBacks"));

        public NativeLong version;
        public PlaceholderCallback /*CFDictionaryRetainCallBack*/ retain;
        public PlaceholderCallback /*CFDictionaryReleaseCallBack*/ release;
        public PlaceholderCallback /*CFDictionaryCopyDescriptionCallBack*/ copyDescription;
        public PlaceholderCallback /*CFDictionaryEqualCallBack*/ equal;
        public PlaceholderCallback /*CFDictionaryHashCallBack*/ hash;

        public CFDictionaryKeyCallBacks() {
        }

        public CFDictionaryKeyCallBacks(Pointer p) {
            super(p);
            read();
        }

        @Override
        protected List<String> getFieldOrder() {
            return Arrays.asList("version", "retain", "release", "copyDescription", "equal", "hash");
        }

        public static interface PlaceholderCallback extends Callback {
            void callback();
        }
    }

    public static class CFDictionaryValueCallBacks extends Structure {
        public static final CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks = new CFDictionaryValueCallBacks(
            CoreFoundation.JNA_NATIVE_LIB.getGlobalVariableAddress("kCFTypeDictionaryValueCallBacks"));

        // Structure fields which I don't know what they do yet.
        public NativeLong version;
        public PlaceholderCallback /*CFDictionaryRetainCallBack*/ retain;
        public PlaceholderCallback /*CFDictionaryReleaseCallBack*/ release;
        public PlaceholderCallback /*CFDictionaryCopyDescriptionCallBack*/ copyDescription;
        public PlaceholderCallback /*CFDictionaryEqualCallBack*/ equal;

        public CFDictionaryValueCallBacks() {
        }

        public CFDictionaryValueCallBacks(Pointer p) {
            super(p);
            read();
        }

        @Override
        protected List<String> getFieldOrder() {
            return Arrays.asList("version", "retain", "release", "copyDescription", "equal");
        }

        public static interface PlaceholderCallback extends Callback {
            void callback();
        }
    }
}

There are a lot of fields and methods in here where deleting that one method makes the exception no longer happen, but I can't figure out a pattern...

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions