I am using BlazeDS to communicate between Java and Flash/Flex. And everything works fine, except that Java Null Integer becomes 0 on Flex side.
To handle the problem with transferring a Java Null Integer to an Flash/Flex int, I have implement a custom serialization, which works on the Java side and uses negative values to express Null values.
After implementing that I get an
RangeError: Error #2006: Der angegebene Index liegt außerhalb des zulässigen Bereichs.
(in english: the index is out of range)
at ObjectInput/readObject()
at mx.collections::ArrayList/readExternal()[E:\dev\4.x\frameworks\projects\framework\src\mx\collections\ArrayList.as:586]
at mx.collections::ArrayCollection/readExternal()[E:\dev\4.x\frameworks\projects\framework\src\mx\collections\ArrayCollection.as:147]
at ObjectInput/readObject()
at mx.messaging.messages::AbstractMessage/readExternal()[E:\dev\4.x\frameworks\projects\rpc\src\mx\messaging\messages\AbstractMessage.as:486]
at mx.messaging.messages::AsyncMessage/readExternal()[E:\dev\4.x\frameworks\projects\rpc\src\mx\messaging\messages\AsyncMessage.as:170]
at mx.messaging.messages::AcknowledgeMessage/readExternal()[E:\dev\4.x\frameworks\projects\rpc\src\mx\messaging\messages\AcknowledgeMessage.as:95]
The exception occures on the Flex side while deserializing the Java Result.
Which is an list of complex objects which contains this special class with the custom serialization. Because there was no such problem until I added the custom serialization, I guess it must belong to the problem, but i have no clue what triggers the exception.
This is the code of the object with the custom serialization:
package crux.domain.dto;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;
public class NullAbleID implements Serializable, Externalizable {
private static final long serialVersionUID = 788620879056753289L;
private Integer id;
public NullAbleID() {
super();
this.id = null;
}
public NullAbleID(final Integer id) {
this.id = id;
}
getter, setter for ID and hashCode and equals
#Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(this.nullToNegative(this.id));
}
#Override
public void readExternal(ObjectInput in) throws IOException {
this.id = this.negativeToNull(in.readInt());
}
private int nullToNegative(Integer id) {
if (id == null) {
return -1;
} else {
return id.intValue();
}
}
private Integer negativeToNull(int flashId) {
if (flashId < 0) {
return null;
} else {
return Integer.valueOf(flashId);
}
}
}
Flex: two classes, because we use Gas3 Granite Data Service code generation:
/**
* Generated by Gas3 v2.1.0 (Granite Data Services).
*
*/
package crux.domain.dto {
import flash.utils.IExternalizable;
[Bindable]
public class NullAbleIDBase {
public function NullAbleIDBase() {}
private var _id:Number;
public function set id(value:Number):void {
_id = value;
}
public function get id():Number {
return _id;
}
}
}
Flex sub class with read and write external
package crux.domain.dto {
import flash.utils.IDataInput;
import flash.utils.IDataOutput;
import flash.utils.IExternalizable;
[Bindable]
[RemoteClass(alias="crux.domain.dto.NullAbleID")]
public class NullAbleID extends NullAbleIDBase implements IExternalizable{
public function readExternal(input:IDataInput):void {
id = input.readInt();
}
public function writeExternal(output:IDataOutput):void {
output.writeInt(id);
}
}
}
I have spend several hours on this problem, but I have no idea what the problem is.
Do you see the cause for the exception?
Not sure it's the cause of the problem, because I don't know BlazeDS, but the methods readExternal and writeExternal of your NullAbleID class are not symetric : you write an object of type Integer in writeExternal, and you read an int in readExternal.
Related
I'm writing a java application that has users that create contracts. The contracts have a list of supporting users that can be added to the contract. The user that created this contract is not on the list of supporters. The supporting users can help the initial creator of the user follow through on the contract for example "No alcohol for 60 days."
I've got a function that can display the list of contracts in the user class.
I also can add users to a list in the contract.
How should I approach writing the viewSupportedContracts() function with the best memory issues in mind later on?
I will be using the User object in a main class.
package core;
import java.util.ArrayList;
import java.util.List;
public class Contract {
private boolean termsAndAgreementSigned = false;
private List<User> supporters = new ArrayList<User>();
public Contract()
{
}
public void setTermsAndAgreementSigned(boolean termsAndAgreementSigned) {
this.termsAndAgreementSigned = termsAndAgreementSigned;
}
public boolean isTermsAndAgreementSigned() {
return termsAndAgreementSigned;
}
public void addSupporter(User user)
{
supporters.add(user);
}
public void viewSupporters()
{
System.out.println("These are the supporters");
}
}
package core;
import java.util.ArrayList;
import java.util.List;
public class User {
private List<Contract> contracts = new ArrayList<Contract>();
public User()
{
}
public void addContract(Contract contract) throws Exception {
if(contract.isTermsAndAgreementSigned() == true)
contracts.add(contract);
}
public List<Contract> getContracts() throws Exception {
return contracts;
}
public void viewSupportedContracts() {
// TODO Auto-generated method stub
}
}
It seems that your code to add contracts with users is very efficient in regards to memory and seems to me that you are looking for a way to view the contracts. My approach would be to implement a toString() method in the Contract class and either call toString on the List or write a for loop to print each Contract on a new line
public class Contract {
public String toString() {
return supporters.toString() + " users support you!";
}
}
public class User {
public String toString() {
return "Create generated user text here";
}
public void viewSupportedContracts() {
System.out.println(contracts.toString());
}
}
or
public void viewSupportedContracts() {
for(Contract contract: contracts) {
System.out.println(contract.toString());
}
}
This question already has answers here:
My program keeps saying that the method cannot be resolved
(2 answers)
Closed 5 years ago.
My class Cupple needs to call the method beStored(char) of a class DataIterator that implements an interface StorableData.
Here the code of this interface StorableData :
package general_classes.cupples;
public interface StorableData {
public void beStored(char c);
}
Here the code of the implementation :
package general_classes.cupples;
public class Cupple<TYPE_OF_ELEMENTS> implements StorableData {
public void beStored(char c) {
}
}
And finally, here the code of the class DataIterator :
package general_classes.DataIteration;
public class DataIterator<StorableData> {
private StorableData root_storable_data;
public List<StorableData> iterate() {
this.root_storable_data.beStored(read_character);
}
}
Please note that I didn't write all the lines.
The problem is that the compiler tells me that he "cannot resolve the method beStored(int).
However, as you can see it, it's actually in the interface. So what's the problem ?
COMPLETE CODE.
INTERFACE :
package general_classes.cupples;
public interface StorableData {
public Cupple beStored(int c);
}
IMPLEMENTATION :
package general_classes.cupples;
import java.util.ArrayList;
public class Cupple<TYPE_OF_ELEMENTS> extends ArrayList<TYPE_OF_ELEMENTS> implements StorableData {
private int position_to_insert_element;
private int number_of_elements;
private Cupple<TYPE_OF_ELEMENTS> next_cupple;
private Cupple<TYPE_OF_ELEMENTS> current_empty_cupple;
public Cupple(int number_of_elements) {
this.position_to_insert_element = 0;
this.number_of_elements = number_of_elements;
}
public Cupple beStored(int c) {
Cupple returned_cupple = this;
if(this.position_to_insert_element > this.number_of_elements) {
this.next_cupple = returned_cupple = new Cupple<>(this.number_of_elements);
} else {
//this.add((TYPE_OF_ELEMENTS) c);
this.position_to_insert_element++;
}
return returned_cupple;
}
public Cupple next() {
return this.next_cupple;
}
}
CLASS :
package general_classes.DataIteration;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
/**
* Reads character per character some given data. Stores the character in a
* list, after having casted it in the specified type by the way.
*
* #author e1300478
*
* #param <StorableData>
* the wished type of the reading's returned elements
*/
public class DataIterator<StorableData> {
private Reader reader;
private List<StorableData> returned_elements_list;
private StorableData root_storable_data;
DataIterator(Reader reader, StorableData storable_data) {
this.reader = reader;
this.returned_elements_list = new ArrayList<>();
this.root_storable_data = storable_data;
}
public List<StorableData> iterate() throws IOException {
int read_character;
do {
read_character = this.reader.read();
StorableData storable_data = this.root_storable_data.beStored((int) read_character);
if(!this.returned_elements_list.contains(storable_data)) {
this.returned_elements_list.add(storable_data);
}
} while (read_character > -1);
return this.returned_elements_list;
}
}
The problem is that the compiler tells me that he "cannot resolve the
method beStored(int).
That simply means that you're attempting to pass an int type to the beStored method. If you look at the interface definition of this method again you'll notice that you're not obeying the contract that has been set.
public void beStored(char c);
in the code below read_character is most likely an int type rather than a character hence the error.
this.root_storable_data.beStored(read_character);
Solution
change this:
int read_character;
to this:
char read_character;
also change this:
StorableData storable_data = this.root_storable_data.beStored((int) read_character);
to this:
StorableData storable_data = this.root_storable_data.beStored(read_character);
The problem is this, in DataIterator StorableData is just a generic type, is not the class StorableData, is the same as DataIterator
The following code would compile.
public class DataIterator {
private StorableData root_storable_data;
public List<StorableData> iterate() {
char read_character='x';
this.root_storable_data.beStored(read_character);
return null;
}
}
I would like to write a java rule Will generate a issue if an imported class is an APIClass annotation and the imported class has issues. I am following this tutorial.
The code:
First, I wrote a simple rule:
#Rule( key = "ForbidClassVariables", name = "ForbidClassVariables")
public class ForbidClassVariables extends BaseTreeVisitor implements JavaFileScanner {
private JavaFileScannerContext context;
#Override
public void scanFile(JavaFileScannerContext context) {
this.context = context;
if (context.getSemanticModel() != null) {
scan(context.getTree());
}
}
#Override
public void visitClass(ClassTree tree) {
if (tree.modifiers().annotations().size() > 0 && hasAnnotation(tree.modifiers().annotations(), "APIClass")) {
if (hasClassVariables(tree)) {
this.context.reportIssue(this, tree.simpleName(), "Do not use class variables on API Classes.");
}
}
super.visitClass(tree);
}
private boolean hasAnnotation(List<AnnotationTree> annotations, String annotationName) {
for (AnnotationTree annotation : annotations) {
if (annotation.annotationType().is(Tree.Kind.IDENTIFIER)
&& ((IdentifierTree) annotation.annotationType()).name().equals(annotationName)) {
return true;
}
}
return false;
}
private boolean hasClassVariables(ClassTree tree) {
for (Tree member : tree.members()) {
if (member.is(Tree.Kind.VARIABLE)) {
VariableTree variableTree = (VariableTree) member;
Symbol symbol = variableTree.symbol();
if (!symbol.isStatic() || !symbol.isFinal()) {
return true;
}
}
}
return false;
}
}
I created a test class file ExampleA.java
package br.com.test;
#APIClass
public class ExampleA {
private String name;
}
When I run the test, generates an error on line 4, It was as expected.
The point of the problem: I created another rule:
#Rule( key = "CheckIFClassIsOK", name = "CheckIFClassIsOK")
public class CheckIFImportedClassIsOK extends BaseTreeVisitor implements JavaFileScanner{
private JavaFileScannerContext context;
#Override
public void scanFile(JavaFileScannerContext context) {
this.context = context;
if (context.getSemanticModel() != null) {
scan(context.getTree());
}
}
#Override
public void visitImport(ImportTree tree) {
IdentifierTree identifier = ((MemberSelectExpressionTree) tree.qualifiedIdentifier()).identifier();
System.out.println(identifier); // Shows ExampleA
// At this point I need re-scan ExampleA class and IF the scan generate any issue
// Will generate another here Issue on ExampleB
super.visitImport(tree);
}
}
And used this file to test:
import br.com.test.ExampleA;
public class ExampleB {
private ExampleA exampleA;
}
The problem is, when I am visiting an import, if the imported class has an APIClass annotation and has issues, it will generate an issue on ExampleB.java to avoid using this import because has an issue. I have searched a lot on the Tree classes, but I didn't find anything useful. I think I need to force the re-scan on ExampleA.java, but how? Anyone have ideas?
Sonar version: 6.2
Java plugin version: 4.5.0.8398
Thanks for attention
Unfortunately, this is not possible. There is no way in the API to request parsed tree from another file. However you are able to retrieve semantic information about members in class ExampleB, but this doesn't include annotations.
I am new to using Realm library and was trying to implement it in my android application. Just got stuck at a point where I am trying to section my listview based on the view type of a particular element in my json response.
I have tried to implement the sections with recycler view but the problem is I have 2 view types and addition of headers for those view types was causing an issue. Since Realm doesn't have the support of RecyclerAdapter, I created an implementation that will use a custom adapter that supports the RecyclerView.
So, I though I will use a ListView and try to use a simple interface for each of the Object type to determine the type and then insert the Headers based on the position of the group.
For some reason Realm is not allowing me to implement an interface in a class which extends RealmObject.
This is how that class looks like :
import com.google.gson.annotations.SerializedName;
import io.realm.RealmObject;
import io.realm.annotations.Ignore;
import io.realm.annotations.PrimaryKey;
public class TestClass extends RealmObject implements Subjects {
#PrimaryKey
#SerializedName("subjectID")
private String subjectID;
private String subjectDate;
#SerializedName("subjectDescription")
private String subjectDescription;
public String getSubjectID() {
return subjectID;
}
public void setSubjectID(String subjectID) {
this.subjectID = subjectID;
}
public String getSubjectDate() {
return subjectDate;
}
public void setSubjectDate(String subjectDate) {
this.subjectDate = subjectDate;
}
public String getSubjectDescription() {
return subjectDescription;
}
public void setSubjectDescription(String subjectDescription) {
this.subjectDescription = subjectDescription;
}
#Override
public boolean isSubjectA() {
return true;
}
#Override
public boolean isFoo() {
return false;
}
#Override
public boolean isBar() {
return false;
}
}
And this is the Compilation Error log :
Error:(76, 20) error: Getter isSubject is not associated to any field.
Note: Creating DefaultRealmModule
Warning:File for type 'io.realm.DefaultRealmModule' created in the last round will not be subject to annotation processing.
Warning:File for type 'io.realm.DefaultRealmModuleMediator' created in the last round will not be subject to annotation processing.
2 warnings
I have no idea why is complaining about this issue but its not compiling the project.
I read a few discussion about the issue here : link .. Apparently, there's an open discussion about this issue but any other help will be really appreciated.. Thank you
You have an typo in your field's name, also it shouldn't have prefix, so it would be "subject", and getter must be isSubject()
#Ignore
private boolean subject = false;
public boolean isSubject() {
return subject;
}
.
In a previous post Creating a ToolTip Managed bean
I was able to create a manged bean to collect and display tooltip text with only a single lookup and store them in an Application Scope variable. This has worked great.
I am on the rather steep part of the JAVA learning curve so please forgive me.
I have another managed bean requirement to create a HashMap Application Scope but this time it needs to be of a type String, Object. The application is where I have a single 'master' database that contains most of the code, custom controls, and XPages. This Master Database will point to One or More application databases that will store the Notes Documents specific to the application in question. So I have created in the Master a series of Application Documents that specify the RepIDs of the Application, Help and Rules databases specific to the Application along with a number of other pieces of information about the Application. This should allow me to reuse the same custom control that will open the specific DB by passing it the Application Name. As an example the Master Design DB might point to "Purchasing", "Customer Complaints", "Travel Requests" etc.
The code below works to load and store the HashMap, but I am having trouble retrieving the the data.
The compiler shows two errors one at the public Object get(String key) method and the other at mapValue = this.internalMap.get(key); in the getAppRepID method I think that it is mainly syntax but not sure. I have commented the error in the code where it appears.
/**
*This Class makes the variables that define an application within Workflo!Approval
*available as an ApplicationScope variable.
*/
package ca.wfsystems.wfsAppUtils;
import lotus.domino.Base;
import lotus.domino.Session;
import lotus.domino.Database;
import lotus.domino.View;
import lotus.domino.NotesException;
import lotus.domino.ViewColumn;
import lotus.domino.ViewEntry;
import lotus.domino.ViewEntryCollection;
import lotus.domino.Name;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import com.ibm.xsp.extlib.util.ExtLibUtil;
/**
* #author Bill Fox Workflo Systems WFSystems.ca
* July 2014
* This class is provided as part of the Workflo!Approval Product
* and can be reused within this application.
* If copied to a different application please retain this attribution.
*
*/
public abstract class ApplicationUtils implements Serializable, Map<String, Object> {
private static final long serialVersionUID = 1L;
private Session s;
private Name serverName;
private String repID;
private String thisKey;
private ViewEntryCollection formVECol;
private Vector formNames;
private Database thisDB;
private Database appDB;
private View appView;
private View formView;
private ViewEntry formVE;
private ViewEntry tFormVE;
private ViewEntry ve;
private ViewEntry tVE;
private ViewEntryCollection veCol;
private final Map<String, Object> internalMap = new HashMap<String, Object>();
public ApplicationUtils() {
this.populateMap(internalMap);
}
private void populateMap(Map<String, Object> theMap) {
try{
s = ExtLibUtil.getCurrentSession();
//serverName = s.createName(s.getServerName());
thisDB = s.getCurrentDatabase();
appView = thisDB.getView("vwWFSApplications");
veCol = appView.getAllEntries();
ve = veCol.getFirstEntry();
ViewEntry tVE = null;
while (ve != null) {
rtnValue mapValue = new rtnValue();
tVE = veCol.getNextEntry(ve);
Vector colVal = ve.getColumnValues();
thisKey = colVal.get(0).toString();
mapValue.setRepID(colVal.get(2).toString());
// ...... load the rest of the values .......
theMap.put(thisKey, mapValue);
recycleObjects(ve);
ve = tVE;
}
}catch(NotesException e){
System.out.println(e.toString());
}finally{
recycleObjects(ve, veCol, appView, tVE);
}
}
public class rtnValue{
private String RepID;
private String HelpRepID;
private String RuleRepID;
private Vector FormNames;
public String getRepID() {
return RepID;
}
public void setRepID(String repID) {
RepID = repID;
}
public String getHelpRepID() {
return HelpRepID;
}
public void setHelpRepID(String helpRepID) {
HelpRepID = helpRepID;
}
public String getRuleRepID() {
return RuleRepID;
}
public void setRuleRepID(String ruleRepID) {
RuleRepID = ruleRepID;
}
public Vector getFormNames() {
return FormNames;
}
public void setFormNames(Vector formNames) {
FormNames = formNames;
}
}
public void clear() {
this.internalMap.clear();
this.populateMap(this.internalMap);
}
public boolean containsKey(Object key) {
return this.internalMap.containsKey(key);
}
public boolean containsValue(Object value) {
return this.internalMap.containsValue(value);
}
public Set<java.util.Map.Entry<String, Object>> entrySet() {
return this.internalMap.entrySet();
}
public Object get(String key) {
//error on Object get Method must return a result of type Object
try {
if (this.internalMap.containsKey(key)) {
return this.internalMap.get(key);
}
} catch (Exception e) {
System.out.println(e.toString());
rtnValue newMap = new rtnValue();
return newMap;
}
}
public boolean isEmpty() {
return this.internalMap.isEmpty();
}
public Set<String> keySet() {
return this.internalMap.keySet();
}
public Object put(String key, Object value) {
return this.internalMap.put(key, value);
}
public Object remove(Object key) {
return this.internalMap.remove(key);
}
public int size() {
return this.internalMap.size();
}
public Collection<Object> values() {
return this.internalMap.values();
}
public void putAll(Map<? extends String, ? extends Object> m) {
this.internalMap.putAll(m);
}
public String getAppRepID(String key){
/*get the Replica Id of the application database
* not sure this is the correct way to call this
*/
rtnValue mapValue = new rtnValue();
mapValue = this.internalMap.get(key);
//error on line above Type Mismatch: can not convert Object to ApplicationUtils.rtnValue
String repID = mapValue.getRepID();
}
public static void recycleObjects(Object... args) {
for (Object o : args) {
if (o != null) {
if (o instanceof Base) {
try {
((Base) o).recycle();
} catch (Throwable t) {
// who cares?
}
}
}
}
}
}
For the get() method, the way I handle that kind of situation is create a variable of the correct data type as null, in my try/catch set the variable, and at the end return the variable. So:
Object retVal = null;
try....
return retVal;
For the other error, if you right-click on the error marker, it might give you the opportunity to cast the variable to rtnValue, so:
mapValue = (rtnValue) this.internalMap.get(key)
If you haven't got it, Head First Java was a useful book for getting my head around some Java concepts. It's also worth downloading the FindBugs plugin for Domino Designer from OpenNTF. It will identify errors as well as bad practices. Just ignore the errors in the "local" package!
The problem is that there is an execution path that do not return nothing
public Object get(String key) {
//error on Object get Method must return a result of type Object
try {
if (this.internalMap.containsKey(key)) { // false
return this.internalMap.get(key);
}
} catch (Exception e) {
System.out.println(e.toString());
rtnValue newMap = new rtnValue();
return newMap;
}
}
if key is not present in the internalMap, nothing is thrown, then that method do not return anything.
To fix the problem, return the newMap at the end.
public Object get(String key) {
//error on Object get Method must return a result of type Object
try {
if (this.internalMap.containsKey(key)) {
return this.internalMap.get(key);
}
} catch (Exception e) {
System.out.println(e.toString());
}
rtnValue newMap = new rtnValue();
return newMap;
}
You can inline the return to save the allocation (which is what the compiler will do anyway). I didn't do it just to make it clear in the example.
But still you have a compiler error in getAppRepID method. You are expecting a rtnValue but you send back an Object. You must cast there.
The appropriate way to handle this is, if you know that all values are of a given type, create the map with the proper type.
Have you tried making your internalMap a map of rtnValue instances (so )?