Today I tried to investigate this issue: https://github.com/codenameone/CodenameOne/issues/2975
I'm writing here to ask how I can find exactly what goes wrong. This bug is frustrating.
Basically, on iOS only, I have this error, that happens after some random app usage:
java.lang.NullPointerException
at com_codename1_ui_Form.pointerReleased:3758
at net_informaticalibera_cn1_simpleapi_OuterForm.pointerReleased:360
at com_codename1_ui_Component.pointerReleased:4679
at com_codename1_ui_Display.handleEvent:2289
at com_codename1_ui_Display.edtLoopImpl:1214
at com_codename1_ui_Display.mainEDTLoop:1132
at com_codename1_ui_RunnableWrapper.run:120
at com_codename1_impl_CodenameOneThread.run:176
at java_lang_Thread.runImpl:153
I've overridden the pointerReleased method to see if x and y are acceptable values when the previous exception is thrown, it seems so:
#Override
public void pointerReleased(int x, int y) {
try {
super.pointerReleased(x, y);
} catch (Exception ex) {
Log.p("OuterForm.pointerReleased ERROR, x->" + x + ", y->" + y + ", https://github.com/codenameone/CodenameOne/issues/2975");
Log.e(ex);
SendLog.sendLogAsync();
}
}
Using that override, that is equivalent to the crash protection feature, after the first time that this exception happens the TextArea components are not more usable: the tap on them doesn't open the VKB.
In short, there is a NullPointerException inside the iOS port of Form.pointerReleased: how can I discover which line of that method throws the exception? I hope to find info that can help for the bug resolution.
The problem is that the code of the method public void pointerReleased(int x, int y) of the class Form is all inside a try... finally, that hides the actual cause of the exception.
To get the actual cause, I used the following override in the BaseForm class of my app, that extends Form and that I use as superclass for all other Forms:
#Override
public void pointerReleased(int x, int y) {
try {
Component cmp = instance.getResponderAt(x, y);
if (cmp != null) {
cmp.pointerReleased(x, y);
}
} catch (Exception ex) {
Log.p("BaseForm.pointerReleased ERROR, x->" + x + ", y->" + y + ", https://github.com/codenameone/CodenameOne/issues/2975");
Log.e(ex);
SendLog.sendLogAsync();
}
}
As expected, this gave me the actual cause of the bug, that was inside a lambda expression of a TextArea actionListener: more specifically, the issue was a revalidate on an Container reference that can be null in some circumstances (oddly, this happens only on iOS). After that, I removed the previous override (that broke some functionalities), I fixed my code preventing the revalidate on a null object (with an if condition) and the bug disappeared (I've done a test with a long usage of the app).
Related
I want implements the aggregationFunction by the processKeyedFunction, because the default aggregationFunction does not support rich function,
Besides, I tryed the aggreagationFunction + processWindowFunction(https://ci.apache.org/projects/flink/flink-docs-stable/dev/stream/operators/windows.html), but it also cannot satisfy my needs, so I have to use the basic processKeyedFunction to implement the aggregationFunction, the detail of my problem is as followed:
in processFunction, , I define a windowState for stage the aggregation value of elements, the code is as followed:
public void open(Configuration parameters) throws Exception {
followCacheMap = FollowSet.getInstance();
windowState = getRuntimeContext().getMapState(windowStateDescriptor);
currentTimer = getRuntimeContext().getState(new ValueStateDescriptor<Long>(
"timer",
Long.class
));
in processElement() function, I use the windowState (which is a MapState initiate in open function) to aggregate the window element, and register the first timeServie to clear current window state, the code is as followed:
#Override
public void processElement(FollowData value, Context ctx, Collector<FollowData> out) throws Exception
{
if ( (currentTimer==null || (currentTimer.value() ==null) || (long)currentTimer.value()==0 ) && value.getClickTime() != null) {
currentTimer.update(value.getClickTime() + interval);
ctx.timerService().registerEventTimeTimer((long)currentTimer.value());
}
windowState = doMyAggregation(value);
}
in onTimer() function, first, I register the next timeService in next One minute, and clear the window State
#Override
public void onTimer(long timestamp, OnTimerContext ctx, Collector<FollowData> out) throws Exception {
currentTimer.update(timestamp + interval); // interval is 1 minute
ctx.timerService().registerEventTimeTimer((long)currentTimer.value());
out.collect(windowState);
windowState.clear();
}
but when the program is running , I found that all the windowState in onTimer is empty, but it is not empyt in processElement() function, I don't know why this happens, maybe the execution logic is different, how can I fix this,
Thanks in advance !
new added code about doMyAggregation() part
windowState is a MapState , key is "mykey", value is an self-defined Object AggregateFollow
public class AggregateFollow {
private String clicked;
private String unionid;
private ArrayList allFollows;
private int enterCnt;
private Long clickTime;
}
and the doMyAggregation(value) function is pretty much like this , the function of doMyAggregation is to get all the value whose source field is 'follow', but if there are no values whose field is 'click' during 1 minute, the 'follow' value should be obsolete, in a word , it's like a join operation of 'follow' data and 'click' data,
AggregateFollow acc = windowState.get(windowkey);
String flag = acc.getClicked();
ArrayList<FollowData> followDataList = acc.getAllFollows();
if ("0".equals(flag)) {
if ("follow".equals(value.getSource())) {
followDataList.add(value);
acc.setAllFollows(followDataList);
}
if ("click".equals(value.getSource())) {
String unionid = value.getUnionid();
clickTime = value.getClickTime();
if (followDataList.size() > 0) {
ArrayList listNew = new ArrayList();
for (FollowData followData : followDataList) {
followData.setUnionid(unionid);
followData.setClickTime(clickTime);
followData.setSource("joined_flag"); //
}
acc.setAllFollows(listNew);
}
acc.setClicked("1");
acc.setUnionid(unionid);
acc.setClickTime(clickTime);
windowState.put(windowkey, acc);
}
} else if ("1".equals(flag)) {
if ("follow".equals(value.getSource())) {
value.setUnionid(acc.getUnionid());
value.setClickTime(acc.getClickTime());
value.setSource("joined_flag");
followDataList.add(value);
acc.setAllFollows(followDataList);
windowState.put(windowkey, acc);
}
}
because of performance problem, original windowAPI is not a valid choice for me, the only way here I think is to use processFunction + ontimer and Guava Cache ,
Thanks a lot
If windowState is empty, it would be helpful to see what doMyAggregation(value) is doing.
It's difficult to debug this, or propose good alternatives, without more context, but out.collect(windowState) isn't going to work as intended. What you might want to do instead would be to iterate over this MapState and collect each key/value pair it contains to the output.
I changed the type of windowState from MapState to ValueState, and the problem is solved, maybe it is a bug or something, can anyone can explain this?
I looked into drag and drop and found that the drop method of Container shuffles the containers components.
That brought me to ask myself: wouldn't it be nice if drop happened continously while keeping on dragging.
So I did just that - only it yields strange results. Apparently it gets into a state where the dragged component is not painted anymore and the dragFinished method of the dragged component is not called when releasing the pointer.
Please help me understanding what is going wrong there.
Here is the code:
public class FormContinuousDrop extends Form {
private class LabelDraggable extends Label {
int pressedX = 0;
public LabelDraggable(String aCaption) {
super(aCaption);
setDraggable(true);
}
#Override
public void pointerPressed(int x, int y) {
super.pointerPressed(x, y);
pressedX = x;
}
#Override
public void pointerDragged(int x, int y) {
Log.p("LabelDraggable.pointerDragged(" + x + ", " + y + ")");
super.pointerDragged(pressedX, y);
{ // Here is where the "list" is shuffled whilst remaining dragging
if (isDragActivated() && !getAnimationManager().isAnimating()) {
ContainerDropTarget containerDropTarget = (ContainerDropTarget) getParent();
containerDropTarget.drop(this, pressedX, getDraggedy());
}
}
}
#Override
protected void dragFinished(int x, int y) {
Log.p("LabelDraggable.dragFinished(" + x + ", " + y + ")");
super.dragFinished(x, y);
}
}
private class ContainerDropTarget extends Container {
public ContainerDropTarget() {
super(new BoxLayout(BoxLayout.Y_AXIS));
setDropTarget(true);
}
#Override
public Component getComponentAt(int x, int y) {
boolean edt = Display.getInstance().isEdt();
Log.p("ContainerDropTarget.getComponentAt(" + x + ", " + y + ") - EDT: " + String.valueOf(edt));
return super.getComponentAt(x, y);
}
#Override
public void drop(Component dragged, int x, int y) {
Log.p("ContainerDropTarget.drop(" + x + ", " + y + ")");
super.drop(dragged, x, y);
}
}
public FormContinuousDrop() {
setTitle("FormContinuousDrop");
setScrollable(false);
Container containerContent = getContentPane();
containerContent.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
containerContent.add(new SpanLabel("Simple Drag And Drop example where drop is done continously whilst dragging"));
ContainerDropTarget containerDropTarget = new ContainerDropTarget();
for (int tally = 0; tally < 20; tally++) {
containerDropTarget.add(new LabelDraggable("draggable " + (tally + 1)));
}
containerContent.add(containerDropTarget);
}
}
If you have some animation pending then the remove/add might create an animation and defer things like the removal/addition to prevent collision between multiple animations. You should always check the actual status of the component before adding/removing.
Ok, what I tried to do cannot be done for now and for those reasons:
The method com.codename1.ui.Container.drop(Component, int, int) indirectly causes the variable Form.dragged to be set to zero, which in turn causes the drag to be interrupted - see issue https://github.com/codenameone/CodenameOne/issues/1992
If the method com.codename1.ui.AnimationManager.isAnimating() returns false this doesn't mean no animation is in progress - see issue https://github.com/codenameone/CodenameOne/issues/1993
com.codename1.ui.Component.dragFinishedImpl(int, int) scrolls the drop target container using screen coordinates which often leads to strange results with scrollable containers - see issue https://github.com/codenameone/CodenameOne/issues/1994
It would be difficult to find workarounds for the mentioned things because often only private or package private access exists and Codename One does not support overshadowing of classes.
On the other hand, I do not feel familiar enough with Codename One to make the appropriate changes myself and post a pull request.
com.google.apphosting.api.ApiProxy$RequestTooLargeException: The request to API call datastore_v3.Put() was too large.
public static List<Area> readAreas(URL url) {
List<Area> areas = new ArrayList<Area>();
try {
BufferedReader br = new BufferedReader(new FileReader(new File(url.toURI())));
String row;
while ((row = br.readLine()) != null) {
if (row.contains(SEARCHED_ROW)) {
//get the part after "c"
String coord[] = (row.split("c"));
String startCoordM = ((coord[0].trim()).split(" "))[1];
String curvesCoord= coord[1];
Area area = new Area();
area.mPoint= Point.toStartPoint(Point.readPoints(startCoordM));
area.curves = Curve.readCurves (curvesCoord);
areas.add(area);
}
}
br.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return areas;
}
This method runs without any errors but when I log out and log in to the same page of my web application this method runs again and again without problem but then this exception is thrown. I'm using google app engine 1.8.1 with jsf2 and primefaces 3.5. This method is invoked from managed bean :
public MapMB () {
eps = EPDAO.getEPList();
populateAdvancedModel(eps);
drawPolilines();
}
void drawPolilines() {
List<Area> areas = Area.readAreas(getFacesContext().getClass().getResource("/map-inksc.svg") );
for (Area area : areas) {
List<Curve> curves = area.getCurves();
Point endPoint = area.getmPoint();
Polyline polyline = new Polyline();
polyline.setStrokeWeight(1);
polyline.setStrokeColor("#FF0000");
polyline.setStrokeOpacity(1);
for (Curve curve : curves) {
polyline.getPaths().add( new LatLng(endPoint.getY(),endPoint.getX()) );
// curve start point is the end point of previous curve (endPoint.getX(),endPoint.getY() )
double step = 0.01;
for (double t=0;t<= 1;t=t+step) {
double x = getCoordFromCurve(endPoint.getX(), endPoint.getX() + curve.getP1().getX(),endPoint.getX() + curve.getP2().getX(),endPoint.getX() + curve.getP3().getX(), t);
double y = getCoordFromCurve(endPoint.getY(), endPoint.getY() + curve.getP1().getY(),endPoint.getY() + curve.getP2().getY(),endPoint.getY() + curve.getP3().getY(), t);
polyline.getPaths().add( new LatLng(y, x) );
}
endPoint = new Point (endPoint.getX() + curve.getP3().getX(), endPoint.getY() + curve.getP3().getY());
}
advancedModel.addOverlay(polyline);
polyline = new Polyline();
}
}
When I don't read any data (don't use readAreas() above) then everything works fine. So how reading from file is connected to this error? I don't understand.
If there is some information that I didn't put here please just say. All these methods run without errors and then this exception is thrown
See the edit
Ok. So ... somehow the problem is solved. How? I'm not sure. So I had:
a.xhtml < include b.xhtml
c.xhtml < include b.xhtml
a.xhtml and c.xhtml had the same method bFilterMethod()
JSF beans:
a, b, c all ViewScoped
b had a and c as Managed Properties
a.xhtml and c.xhtml have bFilterMethod() that getsSome() data from the database and sets aProperty and cProperty(which are the same). I saw in google app engine logs that the method getsSome() runs about 20 times like infinite loop after that the exception was thrown.
Now all beans are request scoped
a.xhtml has aFilterMethod that getsSome() data
b.xhtml has bFilterMethod that getsSome() data
and a and b has c as Managed Property
Hope this helps someone but as I sad I'm not sure what is the exact error but obviously is caused by too big request from the database no matter this request contains only 3 rows (this request is invoked too many times)
EDIT
After so many years I came back to my topic accidentally. The real reason for all this is that GAE saves the session in the datastore and jsf ViewScoped beans are not removed from the session as in normal java application server. So the solution is just don't use ViewScoped beans
I have the following code:
class Sleeper {
public void sleep(long duration) {
try {
Thread.sleep(duration);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
How do I test, with JMockit, that Thread.currentThread().interrupt() is called if Thread.sleep() throws an InterruptedException?
Interesting question. A bit tricky to test because mocking certain methods of java.lang.Thread can interfere with the JRE or with JMockit itself, and because JMockit is (currently) unable to dynamically mock native methods such as sleep. That said, it can still be done:
public void testResetInterruptStatusWhenInterrupted() throws Exception
{
new Expectations() {
#Mocked({"sleep", "interrupt"}) final Thread unused = null;
{
Thread.sleep(anyLong); result = new InterruptedException();
onInstance(Thread.currentThread()).interrupt();
}
};
new Sleeper.sleep();
}
As of JMockit 1.43, this is impossible
JMockit 1.43 added this commit, which checks if you are trying to mock a thread and blacklists it. Now you will get this exception:
java.lang.IllegalArgumentException: java.lang.Thread is not mockable
I am seeing an error be reported quite frequently in my application. I know where it is happening, I just don't know why. The app plays sound effects (not background music), I am using Xna.Audio and I have a timer to call FrameworkDispatcher.Update() in regular intervals. I am using SoundEffect.CreateInstance so I can I have the sound effect loop. It looks like an error happens when changing the volume. I don't know WHY though. Are there known instances when this can fail?
Function ::: Offset
xxx_RaiseException ::: 32
WatsonUnhandledManagedException ::: 300
Dbg_NotifyManagedException ::: 136
FirstPassException ::: 1044
TransitionStub ::: 0
Microsoft.Xna.Framework.Helpers.ThrowExceptionFromErrorCode ::: 76
Microsoft.Xna.Framework.Audio.SoundEffectInstance.set_Volume ::: 232
Microsoft.Xna.Framework.Audio.SoundEffectInstance..ctor ::: 232
Microsoft.Xna.Framework.Audio.SoundEffect.CreateInstance ::: 192
AgiliTrain.PhoneyTools.Media.SoundEffectPlayer..ctor ::: 96
WildSafari.ClassicModeGame.animalVisibleTimer_Tick ::: 344
...snip....
For those asking, here is more code. The SoundEffectPlayer takes a SoundEffect, creates an instance, and kicks off the XNA FrameworkDispatcher (via the GameTimer). This code is taken from PhoneyTools, so go check out the codeplex project if you need more context. When I want to play an effect, I just new up a SoundEffectPlayer, and pass in what I want.
public class SoundEffectPlayer
{
GameTimer _xnaTimer = new GameTimer();
SoundEffectInstance _effect = null;
public float _duration;
public SoundEffectPlayer(SoundEffect effect, bool loop)
{
_effect = effect.CreateInstance();
_effect.IsLooped = loop;
_duration = (float)effect.Duration.TotalSeconds;
}
public void Play(float volume)
{
_xnaTimer.Start();
_effect.Play();
_effect.Volume = volume;
}
public void Stop()
{
_effect.Stop(true);
_xnaTimer.Stop();
}
}
public class GameTimer
{
DispatcherTimer _timer = new DispatcherTimer()
{
Interval = TimeSpan.FromMilliseconds(50),
};
public GameTimer()
{
_timer.Tick += new EventHandler(_timer_Tick);
}
void _timer_Tick(object sender, EventArgs e)
{
FrameworkDispatcher.Update();
}
public void Start()
{
if (!_timer.IsEnabled) _timer.Start();
}
public void Stop()
{
if (_timer.IsEnabled) _timer.Stop();
}
}
Trying to help out, although i don't have a valid fix...
The setter property for SoundEffectInstance is not as simple as one might think:
set
{
lock (this.voiceHandleLock)
{
if (this.IsDisposed)
{
throw new ObjectDisposedException(base.GetType().Name, FrameworkResources.ObjectDisposedException);
}
if ((value < 0f) || (value > 1f))
{
throw new ArgumentOutOfRangeException("value");
}
Helpers.ThrowExceptionFromErrorCode(SoundEffectUnsafeNativeMethods.SetVolume(this.voiceHandle, value));
this.currentVolume = value;
}
}
Basically the part we're after comes in the line before last.
If the call from SoundEffectUnsafeNativeMethods.SetVolume returns any code smaller than 0, the exception you're getting will be triggered.
Here's what's happening inside the unsafe method:
public static unsafe int modopt(IsLong) SetVolume(uint soundEffectInstanceHandle, float volume)
{
lock (SoundEffectSubsystemSyncObject)
{
if ((soundEffectInstanceHandle != 0) && (soundEffectInstanceHandle != uint.MaxValue))
{
CHandleTable* tablePtr = ?g_pTable#CHandleTable##0PAV1#A;
KernelSoundEffectInstance* instancePtr = CHandleTable.LookUp<class Microsoft::Xna::Framework::Audio::KernelSoundEffectInstance>((CHandleTable modopt(IsConst)* modopt(IsConst) modopt(IsConst)) ?g_pTable#CHandleTable##0PAV1#A, soundEffectInstanceHandle, 0);
if (instancePtr == null)
{
return -2147024809;
}
return **(((int*) instancePtr))[0x34](instancePtr, volume);
}
return -2147024809;
}
}
You can try to surround the creation of _effect.CreateInstance with try...catch and rethrow a more comprehensive and helpful exception that will contain for example, information about the SoundEffect object which you're trying to create (basically you can note down all of its field's values for inspection. (not sure that what you get from MS is only a stack trace or the actual exception messaage).
It seems that on WP7, the call to set the volume goes to some OS pointer table that does some magic behind the scenes and looks for the sound effect handle in this table.
If for some reason it is not found or something similar (don't know why, maybe we can take it with XNA developers), it will throw this exception you're getting.
I know this is not a solution but maybe this is a step in the right direction.
Generally, the exception should not be thrown for the situation you are describing, as long as you built the XNA compatibility layer as it should be (details here).
However, I noticed that you are using PhoneyTools.Media.SoundEffectPlayer - what for? It might be the cause of the problem in your situation.
Also, you seem to have ambiguous references - effect and _effect - which one are you working with when playing content?