Super constructor with null reference - actionscript-3

I'm trying to create a subclass in AS3, with 2 parameters in the constructor, but, when I call the constructor of the subclass, I get this message: "TypeError: Error #1009: Cannot access a property or method of a null object reference."
Main Class:
public class Machine extends Observable implements Observer {
public var name: String;
public var ip: String;
public var tires: Array;
private var updateTimer: Timer;
private var req: Request;
public function Machine(name: String, ip: String): void {
this.name = name;
this.ip = ip;
this.tires = new Array();
updateTimer = new Timer(2000, 1);
updateTimer.addEventListener(TimerEvent.TIMER, timedUpdate);
updateTimer.start();
req = new Request();
timedUpdate(null);
}
}
Subclass:
public class MachineOLD extends Machine {
private var _req: Request;
public function MachineOLD(name: String, ip: String): void {
super(name, ip);
_req = new Request();
}
}
Code:
var m: MachineOLD;
m = new MachineOLD("new old machine", "192.168.0.159");
I'm using Adobe Animate version 19.1 (build 349) to build and run the code.

Related

Why does AutoMapper throw an InvalidCastException when mapping this getter-only property?

From what I've read, AutoMapper is supposed to ignore getter-only properties. But with the configuration below the mapper throws an InvalidCastException due to this getter-only property
using AutoMapper;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Model1, Model2>();
});
var mapper = new Mapper(config);
var m1 = new Model1
{
StringList = new List<string> { "String" }
};
var m2 = mapper.Map<Model2>(m1);
public class Model1
{
public List<string> StringList { get; set; }
public IEnumerable<object> Objects => StringList;
}
public class Model2
{
public List<string> StringList { get; set; }
public IEnumerable<object> Objects => StringList;
}
The Map() line throws this exception
AutoMapper.AutoMapperMappingException: 'Error mapping types.'
Inner Exception
InvalidCastException: Unable to cast object of type 'System.Collections.Generic.List`1[System.String]' to type 'System.Collections.Generic.ICollection`1[System.Object]'.
That doesn't apply to collections because they don't need a setter to be mapped, you can simply map into that collection.
See https://docs.automapper.org/en/latest/10.0-Upgrade-Guide.html#all-collections-are-mapped-by-default-even-if-they-have-no-setter

What is the possible error for this retrofit code? I can't understand the connection of my API and MOBILE

I would like to find out the error is from my code or from my api.
This is my API CLASS:
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.POST;
public interface Api {
#POST("/api/Database/NewLocation")
Call<MapDetails> mapDetailLocation(#Body MapDetails mapDetails);
#POST("/api/Registration/RegisterDevice")
Call<RegisterDetails> registerDetails(#Body RegisterDetails
registerAllDetails);
}
SETTER CLASS:
import com.google.gson.annotations.SerializedName;
public class MapDetails {
#SerializedName("SerialNumber")
private String serialNumber;
#SerializedName("Coordinate1")
private String coordinate1;
#SerializedName("Coordinate2")
private String coordinate2;
#SerializedName("DateTime")
private String dateTime;
#SerializedName("Speed")
private String speed;
#SerializedName("Port")
private Integer Port;
public MapDetails(String serialNumber, String coordinate1, String
coordinate2,
String dateTime, String speed, Integer port) {
this.serialNumber = serialNumber;
this.coordinate1 = coordinate1;
this.coordinate2 = coordinate2;
this.dateTime = dateTime;
this.speed = speed;
Port = port;
}
public String getSerialNumber() {
return serialNumber;
}
public void setSerialNumber(String serialNumber) {
this.serialNumber = serialNumber;
}
public String getCoordinate1() {
return coordinate1;
}
public void setCoordinate1(String coordinate1) {
this.coordinate1 = coordinate1;
}
public String getCoordinate2() {
return coordinate2;
}
public void setCoordinate2(String coordinate2) {
this.coordinate2 = coordinate2;
}
public String getDateTime() {
return dateTime;
}
public void setDateTime(String dateTime) {
this.dateTime = dateTime;
}
public String getSpeed() {
return speed;
}
public void setSpeed(String speed) {
this.speed = speed;
}
public Integer getPort() {
return Port;
}
public void setPort(Integer port) {
Port = port;
}
}
Activity Class:
MapDetails mapDetails = new MapDetails("1807200005",
lat,lon, currentDateTimeString, "0", 9090);
setLocation(mapDetails);
private void setLocation(MapDetails mapDetails) {
initializeRetrofit(mapDetails);
}
private void initializeRetrofit(MapDetails mapDetails) {
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl("http://undefine.apisecure.data[![enter image description here][1]][1]")
.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build();
Api locate = retrofit.create(Api.class);
SetMapLocationApiCaller(locate, mapDetails);
}
private void SetMapLocationApiCaller(Api locate, MapDetails
mapDetails) {
Call<MapDetails> call =
locate.mapDetailLocation(mapDetails);
executeCallAsynchronously(call);
}
private void executeCallAsynchronously(Call call) {
call.enqueue(new Callback<MapDetails>() {
#Override
public void onResponse(Call<MapDetails> call,
Response<MapDetails> response) {
Snackbar.make(view,""+ response,
Snackbar.LENGTH_INDEFINITE)
.setAction("Action", null).show();
}
#Override
public void onFailure(Call call, Throwable t) {
Snackbar.make(view, ""+t.getMessage(),
Snackbar.LENGTH_INDEFINITE)
.setAction("Action", null).show();
}
});
}
On my app , this is the response on my app:
but its not added to my sql. But if am using insomia, it would have send the data I've created to the database.
this data was inserted via insomia not on mobile.
You almost reached to the solution. But, you made little mistake while passing parameters to the API request.
As I can see from the screenshot of Insomia app, that API requires JSONArray as parameter but you're sending JSONObject.
Sample JSON parameter
[
{
"SerialNumber" : "1234",
"Coordinate1" : "12.7845874",
"Coordinate2" : "76.4584578",
"DateTime" : "2018-11-14 08:45:00",
"Speed" : "0",
"Port" : 9090
}
]
According to the above JSON structure you need to change the Api.java class to something like this:
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.POST;
import java.util.List; // add import
public interface Api {
#POST("/api/Database/NewLocation")
Call < MapDetails > mapDetailLocation(#Body List<MapDetails> mapDetails);
// ^^^^ changes here
#POST("/api/Registration/RegisterDevice")
Call < RegisterDetails > registerDetails(#Body RegisterDetails registerAllDetails);
}
Add List<MapDetails> to mapDetailLocation() method parameter.
And in Activity or Fragment use above method like this:
//......
// part of the code
MapDetails mapDetails = new MapDetails("1807200005", lat, lon, currentDateTimeString, "0", 9090);
List<MapDetails> data = new ArrayList<>();
data.add(mapDetails);
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl("<BASE_URL>") // change base URL
.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build();
Api locate = retrofit.create(Api.class);
Call<MapDetails> call = locate.mapDetailLocation(data); // NOTICE THE CHANGES IN PARAMETER
call.enqueue(new Callback<MapDetails>() {
#Override
public void onResponse(Call<MapDetails> call, Response<MapDetails> response) {
// do whatever you want
}
#Override
public void onFailure(Call call, Throwable t) {
// log the error message
}
});
Note: Please change base URL according to your requirement.
Edit:
Change method parameters in Activity from MapDetails to List<MapDetails>
// prepare data
MapDetails data = new MapDetails("1807200005", lat, lon, currentDateTimeString, "0", 9090);
// add it to ArrayList
List<MapDetails> mapDetails = new ArrayList<>();
mapDetails.add(data);
// pass it as an argument
private void setLocation(List<MapDetails> mapDetails) {
initializeRetrofit(mapDetails);
}
Change method parameter in initializeRetrofit()
private void initializeRetrofit(List<MapDetails> mapDetails) {
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl("<BASE_URL>") // change base URL
.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build();
Api locate = retrofit.create(Api.class);
SetMapLocationApiCaller(locate, mapDetails);
}
Again change method parameter
private void SetMapLocationApiCaller(Api locate, List<MapDetails> mapDetails) {
Call<MapDetails> call = locate.mapDetailLocation(mapDetails);
executeCallAsynchronously(call);
}

Unmarshalling JSON array via Jettison/Resteasy

Ran into a similar problem like the following forum post:
http://jersey.576304.n2.nabble.com/parsing-JSON-with-Arrays-using-Jettison-td5732207.html
Using Resteasy 2.0.1GA with Jettison 1.2 and getting a problem marshalling arrays when involving namespace mappings. See code below. Basically if the number of array entries are greater than one and namespace mappings are used. Anybody else run into this problem? The Nabble form poster got around it by writing a custom unmarshaller.
I either need to isolate the Jettison bug or write a Resteasy extension of the JettisonMappedUnmarshaller class (which hands over the namespace mappings and unmarshaller to the Jettison Configuration).
The following code doesn't unmarshall (post step) if the properties variables contains 2 or more entries.
public class Experimenting {
#Path("test")
public static class MyResource {
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "Property", propOrder = { "name", "value" })
public static class MyProperty {
#XmlElement(name = "Name", required = true)
protected String name;
#XmlElement(name = "Value", required = true)
protected String value;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
#XmlType(name = "MyElement", propOrder = { "myProperty" })
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "MyElement", namespace = "http://www.klistret.com/cmdb/ci/commons")
#Mapped(namespaceMap = { #XmlNsMap(namespace = "http://www.klistret.com/cmdb/ci/commons", jsonName = "com.klistret.cmdb.ci.commons") })
public static class MyElement {
#XmlElement(name = "MyProperty", namespace = "http://www.klistret.com/cmdb/ci/commons")
protected List myProperty;
public List getMyProperty() {
if (myProperty == null) {
myProperty = new ArrayList();
}
return this.myProperty;
}
public void setMyProperty(List myProperty) {
this.myProperty = myProperty;
}
}
#GET
#Path("myElement/{id}")
#Produces(MediaType.APPLICATION_JSON)
public MyElement getMy(#PathParam("id")
Long id) {
MyElement myElement = new MyElement();
MyProperty example = new MyProperty();
example.setName("example");
example.setValue("of a property");
MyProperty another = new MyProperty();
another.setName("another");
another.setValue("just a test");
MyProperty[] properties = new MyProperty[] { example, another };
myElement.setMyProperty(Arrays.asList(properties));
return myElement;
}
#POST
#Path("/myElement")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public MyElement createMy(MyElement myElement) {
List properties = myElement.getMyProperty();
System.out.println("Properties size: " + properties.size());
return myElement;
}
}
private Dispatcher dispatcher;
#Before
public void setUp() throws Exception {
// embedded server
dispatcher = MockDispatcherFactory.createDispatcher();
dispatcher.getRegistry().addPerRequestResource(MyResource.class);
}
#Test
public void getAndCreate() throws URISyntaxException,
UnsupportedEncodingException {
MockHttpRequest getRequest = MockHttpRequest.get("/test/element/44");
MockHttpResponse getResponse = new MockHttpResponse();
dispatcher.invoke(getRequest, getResponse);
String getResponseBodyAsString = getResponse.getContentAsString();
System.out.println(String.format(
"Get Response code [%s] with payload [%s]", getResponse
.getStatus(), getResponse.getContentAsString()));
MockHttpRequest postRequest = MockHttpRequest.post("/test/element");
MockHttpResponse postResponse = new MockHttpResponse();
postRequest.contentType(MediaType.APPLICATION_JSON);
postRequest.content(getResponseBodyAsString.getBytes("UTF-8"));
dispatcher.invoke(postRequest, postResponse);
System.out.println(String.format(
"Post Response code [%s] with payload [%s]", postResponse
.getStatus(), postResponse.getContentAsString()));
}
}
Do you have to use Jettison? If not I would recommend just switching to use Jackson instead; this typically solves array/list related problems (problem with Jettison is that it converts to XML model, which makes it very hard to tell arrays from objects -- there are bugs, too, but it is fundamentally hard thing to get working correctly).

Is there a Windsor/DynamicProxy logging aspect, I can place as an attribute to my classes/methods?

In the castle stack?
after the answer I came up with this:
namespace Limpens.Windsor.LoggingAspect
{
using System;
using Castle.Core;
using Castle.Core.Interceptor;
using Castle.Core.Logging;
using Castle.MicroKernel;
using Castle.MicroKernel.ModelBuilder;
public class LoggingContributor : IContributeComponentModelConstruction
{
public void ProcessModel(IKernel kernel, ComponentModel model)
{
model.Interceptors.Add(new InterceptorReference(typeof(LoggingInterceptor)));
}
}
public class LoggingInterceptor : IInterceptor
{
private const string Format = "HH:mm:ss:fff";
private readonly ILogger _logger = NullLogger.Instance;
public LoggingInterceptor(ILogger logger)
{
_logger = logger;
}
public int TresholdInMs { get; set; }
#region IInterceptor Members
public void Intercept(IInvocation invocation)
{
var start = DateTime.Now;
invocation.Proceed();
var finished = DateTime.Now;
var duration = (finished - start).Milliseconds;
if (duration < TresholdInMs) return;
var typeName = invocation.TargetType.Name;
var methodName = invocation.Method.Name;
_logger.DebugFormat("{0}.{1} started at {2} and finished at {3}. Took {4} ms.",
typeName,
methodName,
start.ToString(Format),
finished.ToString(Format),
duration);
}
}
out of the box? No I don't think so. It's trivial to do with custom ComponentModel construction contributor though.

Casting an object using 'as' returns null: myObject = newObject as MyObject; // null

I am trying to create a custom object in AS3 to pass information to and from a server, which in this case will be Red5. In the below screenshots you will see that I am able to send a request for an object from as3, and receive it successfully from the java server. However, when I try to cast the received object to my defined objectType using 'as', it takes the value of null. It is my understanding that that when using "as" you're checking to see if your variable is a member of the specified data type. If the variable is not, then null will be returned.
This screenshot illustrates that I am have successfully received my object 'o' from red5 and I am just about to cast it to the (supposedly) identical datatype testObject of LobbyData:
Enlarge
However, when testObject = o as LobbyData; runs, it returns null. :(
Enlarge
Below you will see my specifications both on the java server and the as3 client. I am confident that both objects are identical in every way, but for some reason flash does not think so. I have been pulling my hair out for a long time, does anyone have any thoughts?
AS3 Object:
import flash.utils.IDataInput;
import flash.utils.IDataOutput;
import flash.utils.IExternalizable;
import flash.net.registerClassAlias;
[Bindable]
[RemoteClass(alias = "myLobbyData.LobbyData")]
public class LobbyData implements IExternalizable
{
private var sent:int; // java sentinel
private var u:String; // red5 username
private var sen:int; // another sentinel?
private var ui:int; // fb uid
private var fn:String; // fb name
private var pic:String; // fb pic
private var inb:Boolean; // is in the table?
private var t:int; // table number
private var s:int; // seat number
public function setSent(sent:int):void
{
this.sent = sent;
}
public function getSent():int
{
return sent;
}
public function setU(u:String):void
{
this.u = u;
}
public function getU():String
{
return u;
}
public function setSen(sen:int):void
{
this.sen = sen;
}
public function getSen():int
{
return sen;
}
public function setUi(ui:int):void
{
this.ui = ui;
}
public function getUi():int
{
return ui;
}
public function setFn(fn:String):void
{
this.fn = fn;
}
public function getFn():String
{
return fn;
}
public function setPic(pic:String):void
{
this.pic = pic;
}
public function getPic():String
{
return pic;
}
public function setInb(inb:Boolean):void
{
this.inb = inb;
}
public function getInb():Boolean
{
return inb;
}
public function setT(t:int):void
{
this.t = t;
}
public function getT():int
{
return t;
}
public function setS(s:int):void
{
this.s = s;
}
public function getS():int
{
return s;
}
public function readExternal(input:IDataInput):void
{
sent = input.readInt();
u = input.readUTF();
sen = input.readInt();
ui = input.readInt();
fn = input.readUTF();
pic = input.readUTF();
inb = input.readBoolean();
t = input.readInt();
s = input.readInt();
}
public function writeExternal(output:IDataOutput):void
{
output.writeInt(sent);
output.writeUTF(u);
output.writeInt(sen);
output.writeInt(ui);
output.writeUTF(fn);
output.writeUTF(pic);
output.writeBoolean(inb);
output.writeInt(t);
output.writeInt(s);
}
}
Java Object:
package myLobbyData;
import org.red5.io.amf3.IDataInput;
import org.red5.io.amf3.IDataOutput;
import org.red5.io.amf3.IExternalizable;
public class LobbyData implements IExternalizable
{
private static final long serialVersionUID = 115280920;
private int sent; // java sentinel
private String u; // red5 username
private int sen; // another sentinel?
private int ui; // fb uid
private String fn; // fb name
private String pic; // fb pic
private Boolean inb; // is in the table?
private int t; // table number
private int s; // seat number
public void setSent(int sent)
{
this.sent = sent;
}
public int getSent()
{
return sent;
}
public void setU(String u)
{
this.u = u;
}
public String getU()
{
return u;
}
public void setSen(int sen)
{
this.sen = sen;
}
public int getSen()
{
return sen;
}
public void setUi(int ui)
{
this.ui = ui;
}
public int getUi()
{
return ui;
}
public void setFn(String fn)
{
this.fn = fn;
}
public String getFn()
{
return fn;
}
public void setPic(String pic)
{
this.pic = pic;
}
public String getPic()
{
return pic;
}
public void setInb(Boolean inb)
{
this.inb = inb;
}
public Boolean getInb()
{
return inb;
}
public void setT(int t)
{
this.t = t;
}
public int getT()
{
return t;
}
public void setS(int s)
{
this.s = s;
}
public int getS()
{
return s;
}
#Override
public void readExternal(IDataInput input)
{
sent = input.readInt();
u = input.readUTF();
sen = input.readInt();
ui = input.readInt();
fn = input.readUTF();
pic = input.readUTF();
inb = input.readBoolean();
t = input.readInt();
s = input.readInt();
}
#Override
public void writeExternal(IDataOutput output)
{
output.writeInt(sent);
output.writeUTF(u);
output.writeInt(sen);
output.writeInt(ui);
output.writeUTF(fn);
output.writeUTF(pic);
output.writeBoolean(inb);
output.writeInt(t);
output.writeInt(s);
}
}
AS3 Client:
public function refreshRoom(event:Event)
{
var resp:Responder=new Responder(handleResp,null);
ncLobby.call("getLobbyData", resp, null);
}
public function handleResp(o:Object):void
{
var testObject:LobbyData=new LobbyData;
testObject = o as LobbyData;
trace(testObject);
}
Java Client
public LobbyData getLobbyData(String param)
{
LobbyData lobbyData1 = new LobbyData();
lobbyData1.setSent(5);
lobbyData1.setU("lawlcats");
lobbyData1.setSen(5);
lobbyData1.setUi(5);
lobbyData1.setFn("lulz");
lobbyData1.setPic("lulzagain");
lobbyData1.setInb(true);
lobbyData1.setT(5);
lobbyData1.setS(5);
return lobbyData1;
}
As you already figured out, you should use registerClassAlias as the RemoteClass works out of the box only for Flex projects (as bindable, etc).
Be sure to call registerClassAlias before any serializing / deserializing occurs.
Also, the debugger is showing you the actual tipe of your "o" parameter, which is object. This shows that the player is not correctly mapping the AMF serialized object's class to any of your classes (so, by default, it goes with Object). You should see a LobbyData object in the debugger; otherwise, no matter how you cast / coerce it, it won't work.
The objet needs to be declared before the responder is called.
public function refreshRoom(event:Event)
{
var testObject:LobbyData=new LobbyData;
var resp:Responder=new Responder(handleResp,null);
ncLobby.call("getLobbyData", resp, null);
}
public function handleResp(o:Object):void
{
testObject = o as LobbyData;
trace(testObject);
}
Actually if you want to workaround the type casting you can simply add this to your constructor:
public function dataAwareObject(o:* = null)
{
//TODO: implement function
super();
if(o){
for(var a:* in o)
this[a] = o[a];
}
}
}
Works like a charm.