JNA complex union structure mapping - structure

In JNA,how to map a complex union structure from follows c codes:
typedef struct {
char *vmxSpec;
char *serverName;
char *thumbPrint;
long privateUse;
VixDiskLibCredType credType;//enum type
union VixDiskLibCreds {
struct VixDiskLibUidPasswdCreds {
char *userName;
char *password;
} uid;
struct VixDiskLibSessionIdCreds {
char *cookie;
char *userName;
char *key;
} sessionId;
struct VixDiskLibTicketIdCreds *ticketId;
} creds;
uint32 port;
} VixDiskLibConnectParams;
when i mapping the struct,it throws a NullPointerException:
Exception in thread "Thread-56" java.lang.NullPointerException
at java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:290)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:157)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:146)
at java.util.Arrays.sort(Arrays.java:472)
at java.util.Collections.sort(Collections.java:155)
at com.sun.jna.Structure.sort(Structure.java:889)
at com.sun.jna.Structure.getFields(Structure.java:921)
at com.sun.jna.Structure.deriveLayout(Structure.java:1054)
at com.sun.jna.Structure.calculateSize(Structure.java:978)
at com.sun.jna.Structure.calculateSize(Structure.java:945)
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.test.vmm.vdp.VixDiskLibrary$VixDiskLibConnectParams.<init>(VixDiskLibrary.java:71)
at com.test.vmm.vdp.VixDiskLibrary$VixDiskLibConnectParams$ByReference.<init>(VixDiskLibrary.java:72)
at com.test.vmm.vdp.VixDiskLib.run(VixDiskLib.java:47)
at java.lang.Thread.run(Thread.java:744)
my code as follows:
public static class VixDiskLibConnectParams extends Structure {
public static class ByReference extends VixDiskLibConnectParams implements Structure.ByReference {}
public static class ByValue extends VixDiskLibConnectParams implements Structure.ByValue {}
public static class VixDiskLibCreds extends Union {
public static class ByReference extends VixDiskLibCreds implements Structure.ByReference {}
public static class ByValue extends VixDiskLibCreds implements Structure.ByValue {}
public VixDiskLibUidPasswdCreds uid;
public VixDiskLibSessionIdCreds sessionId;
public VixDiskLibTicketIdCreds.ByReference ticketId;
public static class VixDiskLibUidPasswdCreds extends Structure {
public static class ByReference extends VixDiskLibUidPasswdCreds implements Structure.ByReference {}
public String userName;
public String password;
protected List getFieldOrder() {
List list = new ArrayList();
list.add(userName);
list.add(password);
return list;
}
}
public static class VixDiskLibSessionIdCreds extends Structure {
public static class ByReference extends VixDiskLibSessionIdCreds implements Structure.ByReference {}
public String cookie;
public String userName;
public String key;
protected List getFieldOrder() {
List list = new ArrayList();
list.add(cookie);
list.add(userName);
list.add(key);
return list;
}
}
public static class VixDiskLibTicketIdCreds extends Structure {
public static class ByReference extends VixDiskLibUidPasswdCreds implements Structure.ByReference {}
protected List getFieldOrder() {
List list = new ArrayList();
return list;
}
}
protected List getFieldOrder() {
List list = new ArrayList();
list.add(uid);
list.add(sessionId);
list.add(ticketId);
return list;
}
}
public String vmxSpec;
public String serverName;
public String thumbPrint;
public NativeLong privateUse;
public int credType;
public VixDiskLibCreds.ByValue creds;
public int port;
public void read() {
super.read();
switch (credType) {
case VixDiskLibCredType.VIXDISKLIB_CRED_UID:
creds.setType(VixDiskLibCreds.VixDiskLibUidPasswdCreds.class);
creds.read();
break;
case VixDiskLibCredType.VIXDISKLIB_CRED_SESSIONID:
creds.setType(VixDiskLibCreds.VixDiskLibSessionIdCreds.class);
creds.read();
break;
case VixDiskLibCredType.VIXDISKLIB_CRED_TICKETID:
creds.setType(VixDiskLibCreds.VixDiskLibTicketIdCreds.class);
creds.read();
break;
case VixDiskLibCredType.VIXDISKLIB_CRED_SSPI:
System.out.println("VixDiskLibCredType : VIXDISKLIB_CRED_SSPI");
break;
default:
System.out.println("VixDiskLibCredType : unknow");
break;
}
}
protected List getFieldOrder() {
List list = new ArrayList();
list.add(vmxSpec);
list.add(serverName);
list.add(thumbPrint);
list.add(privateUse);
list.add(credType);
list.add(creds);
list.add(port);
return list;
}
}
what's wrong?A clear explanation on how to do it will be better.
Thanks

i have found the problem, quotes are forgotten in the method add() when called to add element by List
The correct code will be:
protected List getFieldOrder() {
List list = new ArrayList();
list.add("userName");
list.add("password");
return list;
}

Related

Value Dependent Deserialization with Jackson

I want to deserialize into a data structure. Dependent on the version of the JSON data I want to deserialize into different implementations of the same interface. And this works so far with a custom deserializer.
However, in the data structure I use references. And I expect that when undefined references are encountered an exception is thrown. The way I programmed it, this does not work together with the interface.
I created a small example with a (currently not passing) test case to show the desired behavior.
Additional Information:
In the test case, when I use concrete classes (instead of the interface) in readValue the desired behavior occurs. That is, when I write mapper.readValue(buggy, Database2.class); instead of mapper.readValue(buggy, DatabaseI.class);. But then I lose the ability to abstract from the particular content of the JSON data.
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.btc.adt.pop.scen.objectstreams.Person;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.IntNode;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;
public class Example {
#Test
public void test() throws JsonProcessingException {
ObjectMapper mapper =
new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
SimpleModule module = new SimpleModule();
module.addDeserializer(DatabaseI.class, new ToyDeserializer());
mapper.registerModule(module);
String correct = "{'version':1,'people':[{'id':'a','friends':['b','c']},{'id':'b','friends':['c']},{'id':'c','friends':['b']}]}";
DatabaseI deserCorrect = mapper.readValue(correct, DatabaseI.class);
System.out.println(mapper.writeValueAsString(deserCorrect));
String buggy = "{'version':2,'people':[{'id':'a','friends':['b','c']},{'id':'b','friends':['c']},{'id':'c','friends':['FOO']}]}";
assertThrows(Exception.class, () -> {
mapper.readValue(buggy, DatabaseI.class);
}, "The reference FOO is undefined. An Exception should be thrown.");
}
}
class Person {
#JsonProperty("id")
private String id;
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
#JsonIdentityReference(alwaysAsId = true)
private List<Person> friends = new ArrayList<>();
public Person() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<Person> getFriends() {
return friends;
}
public void setFriends(List<Person> friends) {
this.friends = friends;
}
}
interface DatabaseI {
}
class Database1 implements DatabaseI {
private int version;
private List<Person> people = new ArrayList<>();
public Database1() {
}
public List<Person> getPeople() {
return people;
}
public void setPeople(List<Person> people) {
this.people = people;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
}
class Database2 implements DatabaseI {
private String version;
private List<Person> people = new ArrayList<>();
public Database2() {
}
public List<Person> getPeople() {
return people;
}
public void setPeople(List<Person> people) {
this.people = people;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
}
class ToyDeserializer extends StdDeserializer<DatabaseI> {
protected ToyDeserializer(Class<?> vc) {
super(vc);
}
public ToyDeserializer() {
this(null);
}
#Override
public DatabaseI deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JacksonException {
ObjectMapper mapper = (ObjectMapper) jp.getCodec();
JsonNode node = mapper.readTree(jp);
int version = (Integer) ((IntNode) node.get("version")).numberValue();
if (version == 1) {
return mapper.treeToValue(node, Database1.class);
} else {
return mapper.treeToValue(node, Database2.class);
}
}
}
This very good question! If you want to understand why no exception is thrown, your class Person must look like this:
#JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id",
scope = Person.class,
resolver = SimpleObjectIdResolverThrowsException.class
)
#JsonIdentityReference
class Person {
String id;
List<Person> friends = new ArrayList<>();
#ConstructorProperties({"id"})
public Person(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<Person> getFriends() {
return friends;
}
public void setFriends(List<Person> friends) {
this.friends = friends;
}
}
class SimpleObjectIdResolverThrowsException extends SimpleObjectIdResolver {
public SimpleObjectIdResolverThrowsException() {
super();
}
#Override
public Object resolveId(ObjectIdGenerator.IdKey id) {
if (this._items == null) {
return null;
}
Object obj = this._items.get(id);
if (obj == null) {
throw new RuntimeException("Unresolved reference for: " + id);
}
return obj;
}
#Override
public ObjectIdResolver newForDeserialization(Object context) {
return new SimpleObjectIdResolverThrowsException();
}
}
Now you can set break point in the method resolveId and see what happens when we de-serialize the string "{'version':1,'people':[{'id':'a','friends':['b','c']},{'id':'b','friends':['c']},{'id':'c','friends':['b']}]}":
The problem is that the objects are processed one after the other and the references from the friends list are not resolved at that time.

When arraylist prints objects from 2 classes how to make it print objects from only 1 class

I have this class called Training that extends the other 2 classes
public class Training{
public int workoutTime;
public String typeOfWorkout;
public Training(){
}
public Training(int workoutTime, String typeOfWorkout) {
this.workoutTime = workoutTime;
this.typeOfWorkout = typeOfWorkout;
}
public int getWorkoutTime() {
return workoutTime;
}
public String getTypeOfWorkout() {
return typeOfWorkout;
}
public class Anaerobic extends Training{
public int noOfSets;
public Anaerobic(int workoutTime, String typeOfWorkout, int noOfSets) {
super(workoutTime, ypeOfWorkout);
this.noOfSets = noOfSets;
}
public int getNoOfSets() {
return noOfSets;
}
public class Aerobic extends Training{
public Anaerobic(int workoutTime, String typeOfWorkout) {
super(workoutTime, ypeOfWorkout);
}
public static void main(String[] args) {
Anaerobic anaerobic = new Anaerobic(60, "Strength", 4);
Anaerobic anaerobic1 = new Anaerobic(75, "Strength", 6);
Anaerobic anaerobic2 = new Anaerobic(90, "Strength", 4);
Anaerobic anaerobic3 = new Anaerobic(60, "Strength", 5);
Aerobic aerobic = new Aerobic(60, "Cardio");
ArrayList<Training> list = new ArrayList<>();
list.add(anaerobic);
list.add(anaerobic1);
list.add(anaerobic2);
list.add(anaerobic3);
list.add(aerobic);
showList(list);
And now i have to make a new list and make it print object from either Anaerobic or Aerobic but i have to use the already generated list so i dont know how to do it.
I tried this.
ArrayList listAnaerobic = new ArrayList<>(list);
showListAnaerobic(listAnaerobic);
}
}
public static void showList(ArrayList<Training> lista) {
for (Training list : lista) {
System.out.println(list);
}
public static void showListAnaerobic(ArrayList<Anaerobic> lista) {
for (Anaerobic list : lista) {
System.out.println(list);
}
}

how to make reference type for string enum in kotlin and jacoco coverage testable

Converted a java class into kotlin in Android app, the jacoco coverage starts to show 0 coverage on a compiler generated function, which is not access able. Other ones seem fine in the report.
How to make reference type for string enum in kotlin and jacoco coverage testable
java code:
public final class Message {
private Message() { }
public static class MessageAction {
public static final String OPEN = "open";
public static final String VIEW_ALL = "view_all";
#Retention(RetentionPolicy.SOURCE)
#StringDef({OPEN, VIEW_ALL})
public #interface Action { }
public String mAction;
public MessageAction(#Action String action) {
this.mAction = action;
}
public String getMessageAction() {
return this.mAction;
}
}
}
in kotlin;
import androidx.annotation.StringDef
class Message private constructor() {
class MessageAction(#param:Action var messageAction: String) {
#kotlin.annotation.Retention(AnnotationRetention.SOURCE)
#StringDef(OPEN, VIEW_ALL)
annotation class Action
companion object {
const val OPEN = "open"
const val VIEW_ALL = "view_all"
}
}
}
this is sample of how it is used in java code:
public static void doSomeThing(#Nullable String message, #Message.MessageAction.Action String action) {
...
}
and the test:
#Test
public void test_messageAction() {
String testAction = "open";
Message.MessageAction action = new Message.MessageAction(Message.MessageAction.OPEN);
assertEquals(testAction, action.getMessageAction());
}
the jacoco test coverage result shows 0 covergate on the function setMessageAction(#NotNull String var1) which is in the decompiled java code.
And it is not visible from the code's autocomplete hint.
the kotlin decompiled java code:
public final class Message {
private Message() {
}
#Metadata( ...... )
public static final class MessageAction {
#NotNull
private String messageAction;
#NotNull
public static final String OPEN = "open";
#NotNull
public static final String VIEW_ALL = "view_all";
public static final Message.MessageAction.Companion Companion = new Message.MessageAction.Companion((DefaultConstructorMarker) null);
#NotNull
public final String getMessageAction() {
return this.messageAction;
}
public final void setMessageAction(#NotNull String var1) { //<=== coverage result shows it is not called
Intrinsics.checkNotNullParameter(var1, "<set-?>");
this.messageAction = var1;
}
public MessageAction(#NotNull String messageAction) {
Intrinsics.checkNotNullParameter(messageAction, "messageAction");
super();
this.messageAction = messageAction;
}
#Retention(AnnotationRetention.SOURCE)
#java.lang.annotation.Retention(RetentionPolicy.SOURCE)
#Metadata( ...... )
public #interface Action {
}
#Metadata( ...... )
public static final class Companion {
private Companion() {
}
// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}
}
adding #JvmField resolves it
class MessageAction(#param:Action messageAction: String) {
#kotlin.annotation.Retention(AnnotationRetention.SOURCE)
#StringDef(OPEN, VIEW_ALL, CLEAR, TOUCH3D, PLAY, PAUSE, DISMISSED)
annotation class Action
#JvmField
var messageAction: String = messageAction
companion object {
const val OPEN = "open"
const val VIEW_ALL = "view_all"
}
}

Spring-data-solr config

i met a problem in Studying with Spring data solr,this is my Configuration Class:
#Configuration
#EnableSolrRepositories(basePackages={"cn.likefund.solr.repository"}, multicoreSupport=true)
public class SolrContext {
static final String SOLR_HOST = "http://192.168.11.157:8080/solr";
#Bean
public SolrClient solrClient() {
return new HttpSolrClient(SOLR_HOST);
}
}
and this is my Repository:
package cn.likefund.solr.repository;
import java.util.List;
import org.springframework.data.solr.repository.SolrCrudRepository;
import cn.likefund.solr.model.Activity;
public interface ActivityRepository extends SolrCrudRepository<Activity, String>{
List<Activity> findByName(String name);
}
when I start the application,the message in console is this
error
When I delete the method findByName in the repository,the application start with no problem, i just want to the method findByName worked,anybody know what should i do with this problem?
here is the Activity Class:
#Entity
#SolrDocument(solrCoreName ="core_activity")
public class Activity implements Serializable{
private static final long serialVersionUID = 1566434582540525979L;
#Id
#Field(value = "id")
private String id;
#Field(value = "CREATEDT")
private String createdt;
#Indexed
#Field(value = "NAME")
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCreatedt() {
return createdt;
}
public void setCreatedt(String createdt) {
this.createdt = createdt;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
So, obviously the CrudRepository is not created .
when you delete the findByName, can you manually query your repo ? (just to be sure the problem comes from the method, and not the SOLR schema)
have you tried to annotate annotate the method to explicitly set the query ? Something like
#Query("NAME:?0")
List findByName(String name);

Javafx dynamic Table

I want create dynamic table with TableView class.
I send to contractor the number of columns (int), columns name (String[]) and rows (Student), but I can't deal with that.
How I need to define the TableColumn for each one of columns?
public class DynamicTable extends TableView<Student>{
private ObservableList<Student> data;
private int columnCount;
private String[] columnName;
private TableView<Student> tableView;
DynamicTable(){
}
DynamicTable(int columnCount, Student[] rows, String[] columnName){
this.columnName=columnName;
this.columnCount=columnCount;
data = FXCollections.observableArrayList();
setData(rows);
}
public void buildTable(){
for(int i=0 ; i<columnCount; i++){
final int j=i;
TableColumn<Student,String> col = new TableColumn<Student,String>(columnName[i]);
//col.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Student,String>, ObservableValue<String>>() {
//#Override
//public ObservableValue<String> call(
// CellDataFeatures<Student, String> param) {
// return new SimpleStringProperty(param.getValue().getAddress());
// }
//});
tableView.getColumns().addAll(col);
tableView.setItems(data);
}
}
public void setData(Student[] rows){
data.setAll(rows);
}
public String[] getColumnName(){
return this.columnName;
}
}
I be glad for receiving your answer.
Edit: Student class:
public class Student implements Externalizable
{
private final SimpleIntegerProperty ID;
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
private final SimpleStringProperty address;
private final SimpleObjectProperty<Date> birthDate;
private final SimpleStringProperty department;
private final SimpleIntegerProperty pointsAmount;
private final SimpleObjectProperty<Date> startStudyingDate;
private final SimpleIntegerProperty failedAmount;
private final SimpleDoubleProperty average;
private final SimpleIntegerProperty lavelByGrade;
private final SimpleStringProperty pic;
public Student(){
this.ID = new SimpleIntegerProperty();
this.firstName= new SimpleStringProperty();
this.lastName= new SimpleStringProperty();
this.address= new SimpleStringProperty();
this.birthDate= new SimpleObjectProperty<Date>();
this.department= new SimpleStringProperty();
this.pointsAmount= new SimpleIntegerProperty();
this.startStudyingDate= new SimpleObjectProperty<Date>();
this.failedAmount= new SimpleIntegerProperty();
this.average= new SimpleDoubleProperty();
this.lavelByGrade= new SimpleIntegerProperty();
this.pic = new SimpleStringProperty();
}
public Student(int ID, String firstName, String lastName, String address,
Date birthDate, String department,
int pointsAmount, Date startStudyingDate, int failedAmount,
double average, int lavelByGrade, String pic){
this.ID= new SimpleIntegerProperty(ID);
this.firstName= new SimpleStringProperty(firstName);
this.lastName= new SimpleStringProperty(lastName);
this.address= new SimpleStringProperty(address);
this.birthDate= new SimpleObjectProperty<Date>(birthDate);
this.department= new SimpleStringProperty(department);
this.pointsAmount= new SimpleIntegerProperty(pointsAmount);
this.startStudyingDate= new SimpleObjectProperty<Date>(startStudyingDate);
this.failedAmount= new SimpleIntegerProperty(failedAmount);
this.average= new SimpleDoubleProperty(average);
this.lavelByGrade= new SimpleIntegerProperty(lavelByGrade);
this.pic = new SimpleStringProperty(pic);
}
public int getID() {
return ID.get();
}
public void setID(int ID) {
this.ID.set(ID);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String firstName) {
this.firstName.set(firstName);
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String lastName) {
this.lastName.set(lastName);
}
public String getAddress() {
return address.get();
}
public void setAddress(String address) {
this.address.set(address);
}
public Date getBirthDate() {
return birthDate.get();
}
public void setBirthDate(Date birthDate) {
this.birthDate.set(birthDate);
}
public String getDepartment() {
return department.get();
}
public void setDepartment(String department) {
this.department.set(department);
}
public int getPointsAmount() {
return pointsAmount.get();
}
public void setPointsAmount(int pointsAmount) {
this.pointsAmount.set(pointsAmount);
}
public Date getStartStudyingDate() {
return startStudyingDate.get();
}
public void setStartStudyingDate(Date startStudyingDate) {
this.startStudyingDate.set(startStudyingDate);
}
public int getFailedAmount() {
return failedAmount.get();
}
public void setFailedAmount(int failedAmount) {
this.failedAmount.set(failedAmount);
}
public double getAverage() {
return average.get();
}
public void setAverage(Double average) {
this.average.set(average);
}
public int getLavelByGrade() {
return lavelByGrade.get();
}
public void setLavelByGrade(int lavelByGrade) {
this.lavelByGrade.set(lavelByGrade);
}
public String getPic() {
return pic.get();
}
public void setPic(String pic) {
this.pic.set(pic);
}
#Override
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
setID(in.readInt());
setFirstName((String)in.readObject());
setLastName((String)in.readObject());
setAddress((String)in.readObject());
setBirthDate((Date)in.readObject());
setDepartment((String)in.readObject());
setPointsAmount(in.readInt());
setStartStudyingDate((Date)in.readObject());
setFailedAmount(in.readInt());
setAverage(in.readDouble());
setLavelByGrade(in.readInt());
setPic((String)in.readObject());
}
#Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(getID());
out.writeObject(getFirstName());
out.writeObject(getLastName());
out.writeObject(getAddress());
out.writeObject(getBirthDate());
out.writeObject(getDepartment());
out.writeInt(getPointsAmount());
out.writeObject(getStartStudyingDate());
out.writeInt(getFailedAmount());
out.writeDouble(getAverage());
out.writeInt(getLavelByGrade());
out.writeObject(getPic());
}
}
First, you need to add property accessor methods to your Student class:
public class Student {
private final SimpleStringProperty firstName ;
// etc ...
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String firstName) {
this.firstName.set(firstName);
}
// Add methods like this:
public StringProperty firstNameProperty() {
return firstName ;
}
// ... etc
}
Then your cell value factory will look something like this:
TableColumn<Student,String> col = new TableColumn<Student,String>(columnName[i]);
col.setCellValueFactory(cellData -> {
Student student = cellData.getValue();
return student.xxxProperty();
});
Where you replace xxxProperty() with the actual property whose value you want to display in that column.