Error: static class forcing UnsupportedOperationException - java

I have a class that contains a static method for execute a external program using CreateProcess api from JNA (Java NAtive Access).
PS: I'm making based in this code found here in SO.
My trouble is that when put ProcessInformation class and StartupInfoA as static classes for use this in method described above, this forces a #Override of type:
#Override
protected List getFieldOrder() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
And I never have success for execute my project :-(. See:
So, i ask to you: - Exist some solution for it?
Here is how i'm making all process for obtain my goal:
package myProgram;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.WString;
import static com.sun.jna.platform.win32.WinBase.STARTF_USESHOWWINDOW;
import static com.sun.jna.platform.win32.WinUser.SW_SHOWNORMAL;
import com.sun.jna.win32.StdCallLibrary;
import java.util.List;
public class Execute {
public interface Kernel32 extends StdCallLibrary {
Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
boolean CreateProcessA(
String lpApplicationName
, String lpCommandLine
, Structure lpProcessAttributes
, Structure lpThreadAttributes
, boolean bInheritHandles
, int dwCreationFlags
, Structure lpEnvironment
, String lpCurrentDirectory
, Structure lpStartupInfo
, Structure lpProcessInformation);
}
public static class ProcessInformation extends Structure {
public Pointer hProcess;
public Pointer hThread;
public int dwProcessId;
public int dwThreadId;
#Override
protected List getFieldOrder() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
public static class StartupInfoA extends Structure {
public int cb;
public WString lpReserved;
public WString lpDesktop;
public WString lpTitle;
public int dwX;
public int dwY;
public int dwXSize;
public int dwYSize;
public int dwXCountChars;
public int dwYCountChars;
public int dwFillAttribute;
public int dwFlags;
public short wShowWindow;
public short cbReserved2;
public Pointer lpReserved2;
public Pointer hStdInput;
public Pointer hStdOutput;
public Pointer hStdError;
#Override
protected List getFieldOrder() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
public static void ExecuteProc(String software){
ProcessInformation processInformation = new ProcessInformation();
StartupInfoA startupInfo = new StartupInfoA();
startupInfo.dwFlags = STARTF_USESHOWWINDOW;
startupInfo.wShowWindow = SW_SHOWNORMAL;
Kernel32.INSTANCE.CreateProcessA(software, null
, null
, null
, true
, 0
, null
, null
, startupInfo
, processInformation);
}
}

The purpose of the getFieldOrder method is to provide the names and the order in which fields appear in a class that represents a Structure. You need to do the following :
ProcessInformation
Replace the getFieldOrder method as follows :
#Override
protected List getFieldOrder() {
return Arrays.asList(new String[] { "hProcess", "hThread", "dwProcessId", "dwThreadId" });
}
Similarly for StartupInfoA, return a list containing the names of the fields in StartupInfoA in the order in which they appear.

Related

How to implement a single ArrayList in parent class that's in common to all extending classes?

I have various classes that extend a single class, NormalizedTransfer, where I want to store some data (and do some other things, like transfer the list of normalizations somewhere). The parent class is:
public abstract class NormalizedTransfer
{
protected final List< Normalized > normalizedList = new ArrayList<>();
}
...and subclasses are defined like this:
public class BundleNormalizer extends NormalizedTransfer...
public class PatientNormalizer extends NormalizedTransfer...
public class ObservationNormalizer extends NormalizedTransfer...
public class ProcedureNormalizer extends NormalizedTransfer...
public class EncounterNormalizer extends NormalizedTransfer...
Each of the subclasses does something like this:
public class BundleNormalizer extends NormalizedTransfer
{
public void normalize()
{
normalizedList.add( new Normalized( /* some specification of a normalization accomplished */ ) );
}
}
Here, I show a simplified version of those classes (for bundles) after the essence of NormalizedTransfer which is supposed to hold all discovered normalizations of all normalizers (and do other stuff), PatientNormalizer, ObservationNormalizer, etc. (plus BundleNomalizer, obviously).
Only, when I analyse a the next patient in a document, and instantiate a new PatientNormalizer, the normalizedList of NormalizedTransfer is a different list that the one for a bundle, than the other one for an observation, etc.
Of course it is; I know this. I'm probably looking for a "pattern" to implement.
Also, all of this code will be executed by myriad other threads handling each a separate medical document. So, what I'm asking for is a single (simple) database (ArrayList) bookkeeping a list of normalizations that I'm recording for a whole document no matter what the type and how many resources (patients, observations, accounts, etc.) are encountered. And it can't have anything to do with whatever's being found in other documents.
I'd adapt the naming: ...Transmitter instead of ...Transfer since transfer is a process, not the thing that performs it.
I'd decouple things since the task of a transmitter is to transmit, not to hold data.
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
public class NormalizedList<T> extends AbstractList<T> {
List<T> list = new ArrayList<>();
#Override
public void add( final int index, final T element ) {
list.add( index, element );
}
#Override
public T get( final int index ) {
return list.get( index );
}
#Override
public T remove( final int index ) {
return list.remove( index );
}
#Override
public int size() {
return list.size();
}
void transmitWith( final Class<?> clazz ) throws NoSuchMethodException, SecurityException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
clazz.getMethod( "transmit", List.class ).invoke( null, this );
}
}
public class NormalizedTransmitter {
public static void transmit( final List<?> list ) {
System.out.printf( "NormalizedTransmitter transmitting %d items of %s...%n",
list.size(), list.getClass().getName() );
}
}
public class BundleNormalizer {
private final List<Object> list;
// constructor injection here, but any other injection method is conceivable
public BundleNormalizer( final List<Object> list ) {
this.list = list;
}
public void normalize() {
list.add( new Object( /* some specification of a normalization accomplished */ ) );
}
}
public class Main {
public static void main( final String[] args ) {
final NormalizedList<Object> list = new NormalizedList<>();
new BundleNormalizer( list ).normalize();
new BundleNormalizer( list ).normalize();
NormalizedTransmitter.transmit( list );
// output: NormalizedTransmitter transmitting 2 items of NormalizedList...
list.transmitWith( NormalizedTransmitter.class );
// output: NormalizedTransmitter transmitting 2 items of NormalizedList...
}
}
If you want you can make your NormalizedList a Singleton to be safe that there's really just one.
import java.util.ArrayList;
import java.util.List;
public enum NormalizedListSingleton {
INSTANCE;
List<Object> list = new ArrayList<>();
public void add( final Object element ) {
list.add( element );
}
public void add( final int index, final Object element ) {
list.add( index, element );
}
public Object get( final int index ) {
return list.get( index );
}
public Object remove( final int index ) {
return list.remove( index );
}
public int size() {
return list.size();
}
}
public class PatientNormalizer {
private final NormalizedListSingleton list;
// constructor injection here, but any other injection method is conceivable
public PatientNormalizer( final NormalizedListSingleton list ) {
this.list = list;
}
public void normalize() {
list.add( new Object( /* some specification of a normalization accomplished */ ) );
}
}
public class NormalizedTransmitter {
// ...
public static void transmit( final NormalizedListSingleton list ) {
System.out.printf( "Transmitting %d items of %s...%n", list.size(), list.getClass().getName() );
}
}
public class Main {
public static void main( final String[] args ) {
// ...
new PatientNormalizer( NormalizedListSingleton.INSTANCE ).normalize();
new PatientNormalizer( NormalizedListSingleton.INSTANCE ).normalize();
NormalizerTransmitter.transmit( NormalizedListSingleton.INSTANCE );
// output: Transmitting 2 items of NormalizedListSingleton...
}
}
So are you trying to collect all the information into one base List? If so, make a getter for that parent class that is public. Then the classes that extend it just use
super.getMyListName().add(whateverObjectYouWantToAdd);
of course your getter in your parent is
public List getMyListName(){
return myListName; // call if whatever you want of course.
}

How do I use a more specific struct type in place of a more general one?

I am working on a windows device manager which will work with java.
I stick on trying to pass without error SetupDiSetClassInstallParams function. (I am trying disable an device.)
I am running exact same structure(necessary way) in C++ and I do not have any problem.
I am getting ERROR_INVALID_USER_BUFFER error. When I tried get this error in C++ I need to change SP_PROPCHANGE_PARAMS structs values with wrong ones.
My struct declerations:
public static class SP_CLASSINSTALL_HEADER extends Structure {
public static class ByReference extends SP_CLASSINSTALL_HEADER implements Structure.ByReference {
public ByReference() {
}
public ByReference(Pointer memory) {
super(memory);
}
}
public SP_CLASSINSTALL_HEADER() {
cbSize = size();
}
public SP_CLASSINSTALL_HEADER(Pointer memory) {
super(memory);
read();
}
public int cbSize;
public long InstallFunction; **/* <-- this should be int or else buffer size changes, dll cannot place variables on right places. */**
protected List getFieldOrder() {
return Arrays.asList(new String[] { "cbSize", "InstallFunction" });
}
}
public static class SP_PROPCHANGE_PARAMS extends Structure {
public static class ByReference extends SP_PROPCHANGE_PARAMS implements Structure.ByReference {
public ByReference() {
}
public ByReference(Pointer memory) {
super(memory);
}
}
public SP_PROPCHANGE_PARAMS() {
}
public SP_PROPCHANGE_PARAMS(Pointer memory) {
super(memory);
read();
}
public SP_CLASSINSTALL_HEADER ClassInstallHeader = new SP_CLASSINSTALL_HEADER();
public int StateChange;
public int Scope;
public int HwProfile;
protected List getFieldOrder() {
return Arrays.asList(new String[] { "ClassInstallHeader", "StateChange", "Scope", "HwProfile" });
}
}
My function decleration:
boolean SetupDiSetClassInstallParams(WinNT.HANDLE hDevInfo, Pointer deviceInfoData, Pointer classInstallHeader, int size);
How do I calling this function:
SP_PROPCHANGE_PARAMS spPropChangeParams = new SP_PROPCHANGE_PARAMS();
spPropChangeParams.ClassInstallHeader.InstallFunction = DISetupApi.DIF_PROPERTYCHANGE;
spPropChangeParams.Scope = DISetupApi.DICS_FLAG_GLOBAL;
spPropChangeParams.HwProfile = 0;
spPropChangeParams.StateChange = DISetupApi.DICS_DISABLE;
int spPropChangeParamsSize = spPropChangeParams.size();
SP_CLASSINSTALL_HEADER classInstallHeaderReference = new SP_CLASSINSTALL_HEADER(spPropChangeParams.getPointer());
setupApi.SetupDiSetClassInstallParams(hDevInfo, device.getSPDeviceInfoData().getPointer(), classInstallHeaderReference.getPointer(),
spPropChangeParamsSize);
How It works in c++:
SP_PROPCHANGE_PARAMS spPropChangeParams;
spPropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
spPropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
spPropChangeParams.Scope = DICS_FLAG_GLOBAL;
spPropChangeParams.HwProfile = 0;
spPropChangeParams.StateChange = DICS_DISABLE;
SetupDiSetClassInstallParams(hDeviceInfo, &device.getDeviceInfoData(), (SP_CLASSINSTALL_HEADER*)&spPropChangeParams, sizeof(spPropChangeParams));
Actually I mixed and matched too many ways these structs and function I changed variable types of structs and parameter types of function at the end I could not get anything but error. I cannot find what is my mistake. Could you please help me solve this.
Thanks in advance!
When you're passing around a Structure, don't use Structure.getPointer() unless you have to. When you do that, JNA can't automatically synch the native and Java data, and it's error-prone to remember where to do that yourself. In your case, whatever is in the Java fields never gets copied to native memory in your call to setupApi.SetupDiSetClassInstallParams.
Change your function mapping to this:
boolean SetupDiSetClassInstallParams(WinNT.HANDLE hDevInfo, SP_DEVINFO_DATA deviceInfoData, SP_CLASSINSTALL_HEADER classInstallHeader, int size);
and change the invocation to this:
setupApi.SetupDiSetClassInstallParams(hDevInfo, device.getSPDeviceInfoData(), classInstallHeaderReference, spPropChangeParamsSize);
EDIT
If you stick to your original struct definition (where SP_CLASSINSTALL_HEADER is a field), you need to add a function mapping to the interface (extend the interface and create your own instance of the native library):
public interface MySetupApi extends SetupApi {
MySetupApi INSTANCE = (MySetupApi)Native.loadLibrary(MySetupApi.class, W32APIOptions.DEFAULT_OPTIONS);
boolean SetupDiSetClassInstallParams(WinNT.HANDLE hDevInfo, SP_DEVINFO_DATA deviceInfoData, SP_PROPCHANGE_PARAMS propChangeParams, int size);
}

Why simple set and then get on Dynamic Proxy does not persist? (using TinkerPop Frames JavaHandler)

I wanted to add simple getters and setters on a class that implements VertexFrame and I used JavaHandlers for those. For those methods I didn't want to have any interaction with the database. Unfortunately there is not something like #Ignore so I don't have unexpected annotation exceptions. When I set something on the proxy and immediately I do a get after it goes through reflection, nothing is stored. Could be that I shouldn't be using JavaHandlers but something else.. Btw manager.frame returns Java Dynamic Proxy objects (java.lang.reflect.Proxy). Here is the failing test:
package com.tests.testbed;
import org.springframework.util.Assert;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.tg.TinkerGraph;
import com.tinkerpop.blueprints.impls.tg.TinkerGraphFactory;
import com.tinkerpop.frames.FramedGraph;
import com.tinkerpop.frames.FramedGraphFactory;
import com.tinkerpop.frames.modules.javahandler.JavaHandlerModule;
public class testProxy {
public static void main(String args[]){
TinkerGraph graph = TinkerGraphFactory.createTinkerGraph();
FramedGraphFactory framedFactory = new FramedGraphFactory(new JavaHandlerModule());
FramedGraph<TinkerGraph> manager = framedFactory.create(graph);
Vertex vertex = manager.getVertex(1);
IVert vert = manager.frame(vertex, IVert.class);
int testVal = 231;
vert.setTestVar(231);
Assert.state(vert.getTestVar() != testVal, "int was not stored!");
}
}
---------------------
package com.tests.testbed;
import com.tinkerpop.frames.Property;
import com.tinkerpop.frames.VertexFrame;
import com.tinkerpop.frames.modules.javahandler.JavaHandler;
import com.tinkerpop.frames.modules.javahandler.JavaHandlerClass;
#JavaHandlerClass(Vert.class)
public interface IVert extends VertexFrame {
#Property("id")
public int getId();
#Property("id")
public void setId(int id);
#JavaHandler
public void setTestVar(int testVar);
#JavaHandler
public int getTestVar();
}
--------------------
package com.tests.testbed;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.tg.TinkerGraph;
import com.tinkerpop.blueprints.impls.tg.TinkerGraphFactory;
public class Vert implements IVert {
private Vertex vertex;
private int id;
private int testVar;
public void setTestVar(int testVar){
this.testVar = testVar;
}
public int getTestVar(){
return this.testVar;
}
#Override
public Vertex asVertex() {
if (this.vertex == null){
TinkerGraph graph = TinkerGraphFactory.createTinkerGraph();
Vertex v = graph.getVertex(this.getId());
this.vertex = v;
}
return this.vertex;
}
#Override
public int getId() {
return this.id;
}
#Override
public void setId(int id) {
this.id = id;
}
}
Thank you very much.
P.S I have already added this as an issue in case it is a bug: https://github.com/tinkerpop/frames/issues/109
I tried getting the TargetObject but I couldn't. Please let me know if there is any solution for adding non-database data that can persist on Proxies.
You've gone wrong in a couple of places, first of all:
Property key is reserved for all elements: id
Basically you can't use the property value "id" in your #Property("id") annotations.
Secondly, although it doesn't fail, your Vert class should:
implement JavaHandlerContext<Vertex>
be abstract
persist values using the Vertex's properties (local variables are NOT stored in the graph db!)
only implement/override the methods annotated with #JavaHandler
Additionally, you don't need to store the Vertex. Because your IVert interface extends VertexFrame, you have access to the Vertex using the asVertex() method.
You should definitely re-read the documentation, refer to the examples - https://github.com/tinkerpop/frames/wiki/Java-Handler
Here are the re-written/working classes. N.B. I was using Groovy - it should be exactly the same/very similar for Java.
IVert
#JavaHandlerClass(Vert.class)
public interface IVert extends VertexFrame {
#Property("xxid")
public int getId();
#Property("xxid")
public void setId(int id);
#JavaHandler
public void setTestVar(int testVar);
#JavaHandler
public int getTestVar();
}
Vert
abstract class Vert implements JavaHandlerContext<Vertex>, IVert {
public void setTestVar(int testVar){
asVertex().setProperty('foobar', testVar);
}
public int getTestVar(){
return (int)asVertex().getProperty('foobar');
}
}
Main method (Groovy)
def g = TinkerGraphFactory.createTinkerGraph()
FramedGraphFactory factory = new FramedGraphFactory(new JavaHandlerModule())
FramedGraph framedGraph = factory.create(g)
IVert vert = framedGraph.addVertex('myuniqueid', IVert)
vert.setId(123)
vert.setTestVar(456)
IVert vert2 = framedGraph.getVertex('myuniqueid', IVert)
assert vert2.id == 123
assert vert2.testVar == 456

Avoid type casting

I have an empty interface called Data which is implemented by classes DataOne and DataTwo.
I then have a class called DataHolder which contains a Data object.
It looks something like this:
public class DataHolder() {
public Data data;
}
public class DataOne() {
public int importantData;
public int getImportantData() {
return importantData;
}
public int setImportantData(int importantData) {
this.importantData = importantData;
}
}
public class DataTwo() {
public int notSoImportantData;
}
Let's say theres a function which takes a DataHolder object and does some operation on the importantData integer.
public void calculateImportantData(DataHolder dh) {
int importantData = 1234567890;
dh.data.setImportantData(importantData);
}
How can I be sure that the DataHolder contains a DataOne object, without typecasting?
How about:
public class DataHolder<T extends Data> {
public T data;
}
and in your code you will have:
public void calculateImportantData(DataHolder<DataOne> dh) {
int importantData = 1234567890;
dh.data.setImportantData(importantData);
}
and I assume you meant DataOne and DataTwo to implement Data.
first of all , I tweaked your code a little bit ,
1- I created an Interface , Data , containing some random method someMethod() :
package main.interfaces;
public interface Data {
int myData = 0;
public void someMethod();
}
2- then , I created 2 classes called DataOne and DataTwo :
Class DataOne: ( notice how i added the important business method setImportantData() here , this provides total Encapsulation of your work).
package main;
import main.interfaces.Data;
public class DataOne implements Data{
public int importantData;
public int getImportantData() {
return importantData;
}
public void setImportantData(int importantData) {
this.importantData = importantData;
}
#Override
public void someMethod() {
System.out.println("here in DataOne!... ");
}
public void calculateImportantData(int importantData) {
// int importantData = 1234567890;
setImportantData(importantData);
}
}
Class DataTwo:
package main;
import main.interfaces.Data;
public class DataTwo implements Data{
public int notSoImportantData;
#Override
public void someMethod() {
System.out.println("here in DataTwo!...");
}
public void calculateUsualData(DataTwo d2) {
d2.someMethod();
}
}
after that , using Factory Design Pattern ... I created this DataFactory class:
package main.factory;
import main.DataOne;
import main.DataTwo;
import main.interfaces.Data;
public class DataFactory {
public static Data getData(String dataType){
if(dataType == null){
return null;
}
if(dataType.equalsIgnoreCase("DATAONE")){
return new DataOne();
} else if(dataType.equalsIgnoreCase("DATATWO")){
return new DataTwo();
}
return null;
}
}
now , back to your problem solution , I used DataHolder , encapsulating DataFactory here:
package main.holder;
import main.factory.DataFactory;
import main.interfaces.Data;
public class DataHolder {
Data data;
public DataHolder(String dataType){
data = DataFactory.getData(dataType);
}
public Data getData(){
return data;
}
}
now , try to run the application , I added some comments that will appear on your console , and I hope they will be helpful :)
package main.run;
import main.DataOne;
import main.DataTwo;
import main.holder.DataHolder;
import main.interfaces.Data;
public class main {
public static void main(String[] args) {
// lets assume user of the method passed a DataOne Object, you can
// manage it by changing the value of flag string
String flag = "DataOne";
DataHolder dataHolder = new DataHolder(flag);
if (dataHolder.getData() instanceof DataOne) {
System.out
.println("you have a DataOne object , but a Data reference");
System.out
.println("/nso , you need to create a 'reference' to DataOne to work on that object ...");
} else if (dataHolder.getData() instanceof DataTwo) {
System.out
.println("you have a DataTwo object , but a Data reference");
} else {
System.out
.println("you dont have a DataOne nor DataTwo references , it is a "
+ dataHolder.getData().getClass() + " object!");
}
System.out
.println("in order for the compiler to pass the following test , you must cast he RHS ( right hand side ) to match the LHS (left hand side)");
// in order for the compiler to pass the following test , you must cast
// the RHS ( right hand side ) to match the LHS (left hand side)
DataOne d1 = (DataOne) dataHolder.getData();
// in case you wanted to test DataTwo scenario
//DataTwo d2 = (DataTwo) dataHolder.getData();
System.out.println("if you didnt do that , you can make it a Data Object , but you will not be able to access the method 'getImportantData()' created in DataOne");
Data data = dataHolder.getData();
}
}
(note , here the program structure is : you select the type of the data before you start the application , stored in the "flag" variable inside the main method. after that , a call to DataHolder method will be made , after that , you can check the returned object and check if it is what u specified earlier. if you want it to be a little complicated , you can pass the object type in the DataHolder's constructor , and do the check from there , I didn't want to do it just for simplicity. Good Luck)

JNA getFieldOrder() results in names not matching in HashSet() comparison (JNA's Structure.java, line 925)

Running into a maddening blocking error:
Exception in thread "main" java.lang.Error: Structure.getFieldOrder() on class com.luke.generator.GeneratorEngine$VERSION_INFO returns names ([BuildString, ProtocolMajorVer, ProtocolMinorVer]) which do not match declared field names ([BiuldString, ProtocolMajorVer, ProtocolMinorVer])
at com.sun.jna.Structure.getFields(Structure.java:925)
at com.sun.jna.Structure.deriveLayout(Structure.java:1058)
at com.sun.jna.Structure.calculateSize(Structure.java:982)
at com.sun.jna.Structure.calculateSize(Structure.java:949)
at com.sun.jna.Structure.allocateMemory(Structure.java:375)
at com.sun.jna.Structure.<init>(Structure.java:184)
at com.sun.jna.Structure.<init>(Structure.java:172)
at com.sun.jna.Structure.<init>(Structure.java:159)
at com.sun.jna.Structure.<init>(Structure.java:151)
at com.luke.generator.GeneratorEngine$.<init>(GeneratorEngine.java:108)
at com.luke.generator.connectionVersion(GeneratorEngine.java:297)
at com.luke.generator.Main.main(Main.java:161)
Platform: Intel, Windows 8
JRE 1.7, 32-bit (x86)
Eclipse Kepler, Default encoding UTF-8
jna-4.1.0.jar
32-bit CPP DLL - I can confirm that I am loading the library and calling functions that do not include parameters. I also tried passing WStrings and Strings, but that did not address the issue.
Source:
CPP struct:
typedef struct {
UINT32 ProtocolMajorVer;
UINT32 ProtocolMinorVer;
UI_STRING BuildString; // Build version for the application.
} VERSION_INFO;
CPP Function
DLL_EXPORTS RETURN_TYPES ConnectionVersion (VERSION_INFO &Version) {<body omitted>}
Java code:
//Interface definition
public interface UiApi extends StdCallLibrary {
UiApi INSTANCE = (UiApi) Native.loadLibrary(UiApiPath,UiApi.class);
final String PROTOCOLMAJORVERSION = new String("ProtocolMajorVer");
final String PROTOCOLMINORVERSION = new String("ProtocolMinorVer");
final String BUILDSTRING = new String("BuildString");
public static class VERSION_INFO extends Structure {
public static class ByReference extends VERSION_INFO implements Structure.ByReference {}
public static class ByValue extends VERSION_INFO implements Structure.ByValue {}
public int ProtocolMajorVer;
public int ProtocolMinorVer;
public byte[] BiuldString;
protected List getFieldOrder() {
return Arrays.asList(new String[] { "ProtocolMajorVer","ProtocolMinorVer","BuildString" });
}
}
//Connection
public int Connect(byte[] strServerName);
public int Disconnect();
public int CloseProject();
public int ConnectionVersion(VERSION_INFO result);
public int ConnectionVersion(VERSION_INFO.ByReference result);
public int ConnectionVersion(VERSION_INFO.ByValue result);
}
//Engine.connectionVersion() method
public static int connectionVersion() {
int nReturn = 0;
String str = new String("This is my build version\n");
UiApi uiapilib;
uiapilib = UiApi.INSTANCE;
try {
UiApi.VERSION_INFO.ByReference result = new UiApi.VERSION_INFO.ByReference();
result.ProtocolMajorVer = 0;
result.ProtocolMinorVer = 0;
result.BiuldString = str.getBytes();
nReturn = uiapilib.ConnectionVersion(result);
}
catch (Exception e) {
System.out.println("Error=" + e.getLocalizedMessage());
}
return nReturn;
}
//This is the code in main that results in exception
private static Engine engine;
engine = new GeneratorEngine();
engine.connectionVersion();
I must be missing something basic. Is there something in Eclipse that could possibly be causing the HashSet name comparisons in JNA's Structure.java (line 925) that would result in names not matching? From the exception thrown, these definitions look identical.
Thanks for any tips, guidance, fresh perspectives you can offer.
Check your spelling - the field is called BiuldString not BuildString, you have the i and u reversed.

Categories