How can I get the output parameter, which is in a method in a C++ DLL?
public class MyClass {
public int error = 0;
public String MyMethod(){
String str = null;
error = error(str);
if (error == 0){
return str;
}
else
return null;
}
public native int error(String outputparam);
static {
Native.register("MyDLL");
}
}
See this JNA FAQ entry, which explains how to extract a "returned" string from a buffer used as a parameter.
Related
This might be a duplicate. But I cannot find a solution to my Problem.
I have a class
public class MyResponse implements Serializable {
private boolean isSuccess;
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean isSuccess) {
this.isSuccess = isSuccess;
}
}
Getters and setters are generated by Eclipse.
In another class, I set the value to true, and write it as a JSON string.
System.out.println(new ObjectMapper().writeValueAsString(myResponse));
In JSON, the key is coming as {"success": true}.
I want the key as isSuccess itself. Is Jackson using the setter method while serializing? How do I make the key the field name itself?
This is a slightly late answer, but may be useful for anyone else coming to this page.
A simple solution to changing the name that Jackson will use for when serializing to JSON is to use the #JsonProperty annotation, so your example would become:
public class MyResponse implements Serializable {
private boolean isSuccess;
#JsonProperty(value="isSuccess")
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean isSuccess) {
this.isSuccess = isSuccess;
}
}
This would then be serialised to JSON as {"isSuccess":true}, but has the advantage of not having to modify your getter method name.
Note that in this case you could also write the annotation as #JsonProperty("isSuccess") as it only has the single value element
I recently ran into this issue and this is what I found. Jackson will inspect any class that you pass to it for getters and setters, and use those methods for serialization and deserialization. What follows "get", "is" and "set" in those methods will be used as the key for the JSON field ("isValid" for getIsValid and setIsValid).
public class JacksonExample {
private boolean isValid = false;
public boolean getIsValid() {
return isValid;
}
public void setIsValid(boolean isValid) {
this.isValid = isValid;
}
}
Similarly "isSuccess" will become "success", unless renamed to "isIsSuccess" or "getIsSuccess"
Read more here: http://www.citrine.io/blog/2015/5/20/jackson-json-processor
Using both annotations below, forces the output JSON to include is_xxx:
#get:JsonProperty("is_something")
#param:JsonProperty("is_something")
When you are using Kotlin and data classes:
data class Dto(
#get:JsonProperty("isSuccess") val isSuccess: Boolean
)
You might need to add #param:JsonProperty("isSuccess") if you are going to deserialize JSON as well.
EDIT: If you are using swagger-annotations to generate documentation, the property will be marked as readOnly when using #get:JsonProperty. In order to solve this, you can do:
#JsonAutoDetect(isGetterVisibility = JsonAutoDetect.Visibility.NONE)
data class Dto(
#field:JsonProperty(value = "isSuccess") val isSuccess: Boolean
)
You can configure your ObjectMapper as follows:
mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
#Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
{
if(method.hasReturnType() && (method.getRawReturnType() == Boolean.class || method.getRawReturnType() == boolean.class)
&& method.getName().startsWith("is")) {
return method.getName();
}
return super.nameForGetterMethod(config, method, defaultName);
}
});
I didn't want to mess with some custom naming strategies, nor re-creating some accessors.
The less code, the happier I am.
This did the trick for us :
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
#JsonIgnoreProperties({"success", "deleted"}) // <- Prevents serialization duplicates
public class MyResponse {
private String id;
private #JsonProperty("isSuccess") boolean isSuccess; // <- Forces field name
private #JsonProperty("isDeleted") boolean isDeleted;
}
Building upon Utkarsh's answer..
Getter names minus get/is is used as the JSON name.
public class Example{
private String radcliffe;
public getHarryPotter(){
return radcliffe;
}
}
is stored as { "harryPotter" : "whateverYouGaveHere" }
For Deserialization, Jackson checks against both the setter and the field name.
For the Json String { "word1" : "example" }, both the below are valid.
public class Example{
private String word1;
public setword2( String pqr){
this.word1 = pqr;
}
}
public class Example2{
private String word2;
public setWord1(String pqr){
this.word2 = pqr ;
}
}
A more interesting question is which order Jackson considers for deserialization. If i try to deserialize { "word1" : "myName" } with
public class Example3{
private String word1;
private String word2;
public setWord1( String parameter){
this.word2 = parameter ;
}
}
I did not test the above case, but it would be interesting to see the values of word1 & word2 ...
Note: I used drastically different names to emphasize which fields are required to be same.
You can change primitive boolean to java.lang.Boolean (+ use #JsonPropery)
#JsonProperty("isA")
private Boolean isA = false;
public Boolean getA() {
return this.isA;
}
public void setA(Boolean a) {
this.isA = a;
}
Worked excellent for me.
If you are interested in handling 3rd party classes not under your control (like #edmundpie mentioned in a comment) then you add Mixin classes to your ObjectMapper where the property/field names should match the ones from your 3rd party class:
public class MyStack32270422 {
public static void main(String[] args) {
ObjectMapper om3rdParty = new ObjectMapper();
om3rdParty .addMixIn(My3rdPartyResponse.class, MixinMyResponse.class);
// add further mixins if required
String jsonString = om3rdParty.writeValueAsString(new My3rdPartyResponse());
System.out.println(jsonString);
}
}
class MixinMyResponse {
// add all jackson annotations here you want to be used when handling My3rdPartyResponse classes
#JsonProperty("isSuccess")
private boolean isSuccess;
}
class My3rdPartyResponse{
private boolean isSuccess = true;
// getter and setter here if desired
}
Basically you add all your Jackson annotations to your Mixin classes as if you would own the class. In my opinion quite a nice solution as you don't have to mess around with checking method names starting with "is.." and so on.
there is another method for this problem.
just define a new sub-class extends PropertyNamingStrategy and pass it to ObjectMapper instance.
here is a code snippet may be help more:
mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
#Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
String input = defaultName;
if(method.getName().startsWith("is")){
input = method.getName();
}
//copy from LowerCaseWithUnderscoresStrategy
if (input == null) return input; // garbage in, garbage out
int length = input.length();
StringBuilder result = new StringBuilder(length * 2);
int resultLength = 0;
boolean wasPrevTranslated = false;
for (int i = 0; i < length; i++)
{
char c = input.charAt(i);
if (i > 0 || c != '_') // skip first starting underscore
{
if (Character.isUpperCase(c))
{
if (!wasPrevTranslated && resultLength > 0 && result.charAt(resultLength - 1) != '_')
{
result.append('_');
resultLength++;
}
c = Character.toLowerCase(c);
wasPrevTranslated = true;
}
else
{
wasPrevTranslated = false;
}
result.append(c);
resultLength++;
}
}
return resultLength > 0 ? result.toString() : input;
}
});
The accepted answer won't work for my case.
In my case, the class is not owned by me. The problematic class comes from 3rd party dependencies, so I can't just add #JsonProperty annotation in it.
To solve it, inspired by #burak answer above, I created a custom PropertyNamingStrategy as follow:
mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
#Override
public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
{
if (method.getParameterCount() == 1 &&
(method.getRawParameterType(0) == Boolean.class || method.getRawParameterType(0) == boolean.class) &&
method.getName().startsWith("set")) {
Class<?> containingClass = method.getDeclaringClass();
String potentialFieldName = "is" + method.getName().substring(3);
try {
containingClass.getDeclaredField(potentialFieldName);
return potentialFieldName;
} catch (NoSuchFieldException e) {
// do nothing and fall through
}
}
return super.nameForSetterMethod(config, method, defaultName);
}
#Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
{
if(method.hasReturnType() && (method.getRawReturnType() == Boolean.class || method.getRawReturnType() == boolean.class)
&& method.getName().startsWith("is")) {
Class<?> containingClass = method.getDeclaringClass();
String potentialFieldName = method.getName();
try {
containingClass.getDeclaredField(potentialFieldName);
return potentialFieldName;
} catch (NoSuchFieldException e) {
// do nothing and fall through
}
}
return super.nameForGetterMethod(config, method, defaultName);
}
});
Basically what this does is, before serializing and deserializing, it checks in the target/source class which property name is present in the class, whether it is isEnabled or enabled property.
Based on that, the mapper will serialize and deserialize to the property name that is exist.
I have a List<List<String>> dataTableList and I would like to get a specific list from there and put it on my List<String> dataList so that I could loop through that specific lists' value and alter it.
However, whenever I try to do that,I always get an error of:
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to java.util.List.
Here's a sample of how I am trying to assign a specific list from dataTableList to dataList:
//First I looped through the List of Lists and called each list fetched as dataList
for(List<String> dataList : getTryLang().getDataTableList()){
//then, I created an iterator to be used later when I return the List I fetched with altered value
int iter = 0;
//next, I created a for-loop to iterate through the values of the List the I feched
for(int x; x < dataList.size(); x++){
//here, I formatted each value to amount or currency format.
dataList.set(x, getDataConvert().convertAmount(dataList.get(x)));
//finally, after I formatted everything, I returned it or set it to the specific index it's been located before
getTryLang().getDataTableList().set(iter, dataList);
}
iter++;
}
EDIT:
Here's my code and I modified some of it and didn't include some so that I could focus on expressing where the problem occurs.
Here's my TryLang.java:
#ManagedBean
#SessionScoped
public class TryLang implements Serializable {
public TryLang() {}
//declare
private List<List<String>> dataTableList;
//getter setter
public List<List<String>> getDataTableList() {
return dataTableList == null ? dataTableList = new ArrayList<>() : dataTableList;
}
public void setDataTableList(List<List<String>> dataTableList) {
this.dataTableList = dataTableList;
}
}
Then here's my BookOfAccountsController.java:
#ManagedBean
#RequestScoped
public class BooksOfAccountsController implements Serializable {
public BooksOfAccountsController() {}
//declare
#ManagedProperty(value = "#{dataConvert}")
private DataConvert dataConvert;
#ManagedProperty(value = "#{tryLang}")
private TryLang tryLang;
//getter setter NOTE: I wouldn't include other getter setters to shorten the code here :)
public TryLang getTryLang() {
return tryLang == null ? tryLang = new TryLang() : tryLang;
}
public void setTryLang(TryLang tryLang) {
this.tryLang = tryLang;
}
//I would just go straight to the method instead
public void runBooksOfAccounts() throws SystemException, SQLException {
//So there are dbCons here to connect on my DB and all. And I'll just go straight on where the List<List<String>> is being set
//Here's where the List<List<String>> is being set
getTryLang().setDataTableList(getCemf().getFdemf().createEntityManager().createNativeQuery("SELECT crj.* FROM crj_rep crj").getResultList());
getTryLang().setDataTableColumns(getCemf().getFdemf().createEntityManager().createNativeQuery("SELECT col.column_name FROM information_schema.columns col WHERE table_schema = 'public' AND table_name = 'crj_rep'").getResultList());
for (int x = 0; x < getTryLang().getDataTableColumns().size(); x++) {
try {
Integer.parseInt(getTryLang().getDataTableColumns().get(x));
getTryLang().getDataTableColumns().set(x, getDataConvert().accountCodeConvert(getTryLang().getDataTableColumns().get(x)));
//then here is where the error points at
for (List<String> dataList : getTryLang().getDataTableList()) {
try{
int iter = 0;
dataList.set(x, getDataConvert().convertAmount(new BigDecimal(dataList.get(x))));
getTryLang().getDataTableList().set(iter, dataList);
iter++;
}catch(ClassCastException ne){
System.out.println("cannot convert " + ne);
}
}
} catch (NumberFormatException ne) {
//print the error
}
}
}
}
I want to develop an Eclipse plug-in which get all visible variables for a specific method.
For example:
public class testVariable {
String test1;
Object test2;
void method_test1(){
int test3,test4;
}
void method_test2(){
int test5,test6;
//get variable here!!!!
}
}
I just want to get visible variable is: test1, test2,test5,test6 in method method_test2. What can I do?
Actually, JDT can be used outside of a plug-in, i.e., it can be used in a stand-alone Java application.
The following code can return the variables you want:
public static void parse(char[] str) {
ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setSource(str);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
final CompilationUnit cu = (CompilationUnit) parser.createAST(null);
cu.accept(new ASTVisitor() {
public boolean visit(VariableDeclarationFragment var) {
System.out.println("variable: " + var.getName());
return false;
}
public boolean visit(MethodDeclaration md) {
if (md.getName().toString().equals("method_test2")) {
md.accept(new ASTVisitor() {
public boolean visit(VariableDeclarationFragment fd) {
System.out.println("in method: " + fd);
return false;
}
});
}
return false;
}
});
}
The output is:
variable: test1
variable: test2
in method: test5
in method: test6
Check out more examples at JDT tutorials.
I am learning WCF. where I tried to return an object from my service to client after the operation completed from my client as required. But Its not giving any error and also not returning the result.
Service.svc.cs
public class myWCF : ImyWCF
{
public int myAddition(int IP_One, int IP_Two, out int IP_Three)
{
IP_Three = IP_One + IP_Two;
return IP_Three;
}
public MYTYPE mySubstraction()
{
MYTYPE mType = new MYTYPE();
mType.InpOne = 10;
mType.InpTwo = 20;
mType.InpThree = mType.InpTwo - mType.InpOne;
return mType;
}
}
Interface and Classes
[ServiceContract]
public interface ImyWCF
{
[OperationContract]
int myAddition(int IP_One, int IP_Two, out int IP_Three);
[OperationContract]
MYTYPE mySubstraction();
}
[DataContract]
public class myArithmatics
{
[DataMember]
public int IP_One;
[DataMember]
public int IP_Two;
[DataMember]
public int IP_Three;
}
[Serializable]
[DataContractAttribute(IsReference=true)]
public class MYTYPE
{
public int inpOne = 0;
public int inpTwo = 0;
public int inpThree = 0;
[DataMemberAttribute]
public int InpOne
{
get { return inpOne; }
set { inpOne = value; }
}
[DataMemberAttribute]
public int InpTwo
{
get { return inpTwo; }
set { inpTwo = value; }
}
[DataMemberAttribute]
public int InpThree
{
get { return inpThree; }
set { inpThree = value; }
}
}
Client App
Console.WriteLine("Service Started");
ClientMyWCF.ImyWCFClient oMYWcf = new ClientMyWCF.ImyWCFClient();
int INP_One = 10;
int INP_Two = 20;
int INP_Three = 0;
oMYWcf.myAddition(out INP_Three,INP_One,INP_Two);
Console.WriteLine("Out put from Service :"+ INP_Three.ToString());
ClientMyWCF.MYTYPE objMT = new ClientMyWCF.MYTYPE();
objMT.InpOne = 10;
objMT.InpTwo = 20;
//objMT.InpThree = 0;
oMYWcf.mySubstraction();
Console.WriteLine("Out put from Service :" + objMT.InpThree.ToString());
Console.ReadLine();
So any idea how to get the object returned?
I'm not sure why you're using an OUT parameter in the first call when you're returning the result of the operation as well as the OUT parameter.
Also, in the first method call (addition) you have the parameters in the wrong order.
In the second method call, you're not assigning the MYTYPE object to a variable.
I would suggest the following code:
public class myWCF : ImyWCF
{
// remove the OUT parameter
public int myAddition(int IP_One, int IP_Two)
{
return IP_One + IP_Two;
}
public MYTYPE mySubstraction()
{
MYTYPE mType = new MYTYPE();
mType.InpOne = 10;
mType.InpTwo = 20;
mType.InpThree = mType.InpTwo - mType.InpOne;
return mType;
}
}
Use the following in your program code:
Console.WriteLine("Service Started");
ClientMyWCF.ImyWCFClient oMYWcf = new ClientMyWCF.ImyWCFClient();
int INP_One = 10;
int INP_Two = 20;
int INP_Three = 0;
INP_Three = oMYWcf.myAddition(INP_One, INP_Two);
Console.WriteLine("Out put from Service :"+ INP_Three.ToString());
ClientMyWCF.MYTYPE objMT = new ClientMyWCF.MYTYPE();
// Not needed - these are set in the mySubtraction method
//objMT.InpOne = 10;
//objMT.InpTwo = 20;
//objMT.InpThree = 0;
objMT = oMYWcf.mySubstraction();
Console.WriteLine("Out put from Service :" + objMT.InpThree.ToString());
Console.ReadLine();
Remove the SerializableAttribute e.g; [Serializable] because there is no need to be serialize this object.
For class , use attribute [DataContract]
For class level properties , use attribute [DataMemberAttribute]
to expose the method , use attirbute [OperationContract]
these are standards for wcf service.
You can also remove these 2 attributes all together
[Serializable]
[DataContractAttribute(IsReference=true)]
By default, all public properties will be serialized. Also seeing your proxy would help. There are certain classes you should be inheriting from. I'm also not seeing a new instance of ServiceHost(typeof(MyService), myUri) being initialized which is strange. Maybe you have it encapsulated somewhere. Anyway, it's typical to construct a new channel using the ChannelFactory as such and to host a new service as such.
First of all, remove SerializableAttribute, using DataContractAttribute is enough.
Why you use out in myAddition method? it already returns the result through the return value, the third parameter is unnecessary.
In your code, you don't store the result from mySubstraction, while you read the objMT.InpThree that isn't assigned any value, I don't understand.
I have an array of function callbacks, like this:
class Blah {
private var callbacks : Array;
private var local : Number;
public function Blah() {
local = 42;
callbacks = [f1, f2, f3];
}
public function doIt() : Void {
callbacks[0]();
}
private function f1() : Void {
trace("local=" + local);
}
private function f2() : Void {}
private function f3() : Void {}
}
If I run this code, I get "local=undefined" instead of "local=42":
blah = new Blah();
blah.doIt();
So, Flash function pointers don't carry context. What's the best way to solve this problem?
Try:
callbacks[0].apply(this, arguments array)
or
callbacks[0].call(this, comma-separated arguments)
If you want to "carry context" try :
public function doIt() : Void {
var f1() : function (): Void {
trace("local=" + local);
}
f1();
}
This creates a closure on this.local as expected
the most easy way is to use the Delegate class ... it works using the techniques Vlagged described ... although i must amend, that i do not understand the code at all (it is also syntactically incorrect) ...
otherwise, try this:
class AutoBind {
/**
* shortcut for multiple bindings
* #param theClass
* #param methods
* #return
*/
public static function methods(theClass:Function, methods:Array):Boolean {
var ret:Boolean = true;
for (var i:Number = 0; i < methods.length; i++) {
ret = ret && AutoBind.method(theClass, methods[i]);
}
return ret;
}
/**
* will cause that the method of name methodName is automatically bound to the owning instances of type theClass. returns success of the operation
* #param theClass
* #param methodName
* #return
*/
public static function method(theClass:Function, methodName:String):Boolean {
var old:Function = theClass.prototype[methodName];
if (old == undefined) return false;
theClass.prototype.addProperty(methodName, function ():Function {
var self:Object = this;
var f:Function = function () {
old.apply(self, arguments);
}
this[methodName] = f;
return f;
}, null);
return true;
}
}
and add this as the very last declaration in Blah:
private static var __init = AutoBind.methods(Blah, "f1,f2,f3".split(","));
that'll do the trick ... note that calls to f1, f2 and f3 will become slower though, because they need one extra function call ...
greetz
back2dos