e4 ConcurrentModificationException on ESelectionService setSelection - java

I have a code which sets the active selection of the ESelectionService when the user selects something in the tree. Like here:
treeViewer.addSelectionChangedListener(new SelectionChangedListener() {
#Override
public void selectionChanged(SelectionChangedEvent event) {
if (selectionService != null) {
selectionService.setSelection(((IStructuredSelection) event.getSelection()).getFirstElement());
}
}
});
where selectionService is being injected. So far so good.
I also have some command handlers with their own canExecute() methods. In these methods I check the current selection (which is also being injected) and decide if the canExecute() method should return true or false. What I also do in this method is, I also change the visibility of the corresponding HandledToolItem - like here https://stackoverflow.com/a/23602909/2097228.
Now what I experience is that sometimes the call to the setSelection method of the ESelectionService throws a ConcurrentModificationException. This actually occurs when the ToolItemUpdater accesses the itemsToCheck ArrayList.
Is my approach error-prone or is this just a bug in 4.4?
Here is the stacktrace:
Exception occurred
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at org.eclipse.e4.ui.workbench.renderers.swt.ToolItemUpdater.updateContributionItems(ToolItemUpdater.java:36)
at org.eclipse.e4.ui.workbench.renderers.swt.ToolBarManagerRenderer$8.changed(ToolBarManagerRenderer.java:367)
at org.eclipse.e4.core.internal.contexts.TrackableComputationExt.update(TrackableComputationExt.java:110)
at org.eclipse.e4.core.internal.contexts.EclipseContext.processScheduled(EclipseContext.java:338)
at org.eclipse.e4.core.internal.contexts.EclipseContext.set(EclipseContext.java:352)
at org.eclipse.e4.ui.internal.workbench.swt.E4Application$4.changed(E4Application.java:842)
at org.eclipse.e4.core.internal.contexts.TrackableComputationExt.update(TrackableComputationExt.java:110)
at org.eclipse.e4.core.internal.contexts.EclipseContext.processScheduled(EclipseContext.java:338)
at org.eclipse.e4.core.internal.contexts.EclipseContext.set(EclipseContext.java:352)
at org.eclipse.e4.ui.internal.workbench.SelectionAggregator$7.changed(SelectionAggregator.java:228)
at org.eclipse.e4.core.internal.contexts.TrackableComputationExt.update(TrackableComputationExt.java:110)
at org.eclipse.e4.core.internal.contexts.EclipseContext.processScheduled(EclipseContext.java:338)
at org.eclipse.e4.core.internal.contexts.EclipseContext.set(EclipseContext.java:352)
at org.eclipse.e4.ui.internal.workbench.SelectionServiceImpl.setSelection(SelectionServiceImpl.java:31)
at com.e4test.parts.SamplePart$TreeViewerSelectionListener.selectionChanged(SamplePart.java:116)

Related

How to disable image loading in CEF/JCEF?

Is there a switch/flag that allows to do this? I spent hours finding those but couldn't find anything that works. The other thing I'm planning to do is intercept the cefRequest by adding my own CefRequestHandler, examine the resource type and if it matches RT_IMAGE, cancel the request. Everything seems easy except the part when I have to cancel a request. How do I stop/block/cancel a cefRequest? I probably should not be doing it this way but it doesn't work anyway:
public class CefClientRequestHandler extends CefRequestHandlerAdapter {
#Override
public boolean onBeforeResourceLoad(CefBrowser cefBrowser, CefFrame cefFrame, CefRequest cefRequest) {
if (cefRequest.getResourceType().equals(CefRequest.ResourceType.RT_IMAGE)) {
cefRequest.setURL("");
}
return false;
}
// more overides
}
Any ideas?
So here's a hack that works. The trick is to change the Request Method to HEAD, and because HEAD requests aren't returned the body, images won't be part of the response.
public class CefClientRequestHandler extends CefRequestHandlerAdapter {
#Override
public boolean onBeforeResourceLoad(CefBrowser cefBrowser, CefFrame cefFrame, CefRequest cefRequest) {
if (cefRequest.getResourceType().equals(RT_IMAGE)) {
cefRequest.setMethod("HEAD");
}
return false;
}
// other overridden methods here...
}
I believe that this approach should be avoided mainly because of the following two reasons:
Changing the method from GET to HEAD does not prevent CEF from making the request to the server. The overhead of opening a connection and handling a request is still there which makes it slower than simply blocking the request.
I'm not sure if images won't be displayed if they are available from browser cache. Currently, I don't know of any methods to test this. Suggestions are welcome.
Edit 1:
Changing URL didn't work in the example I posted in the question because I was passing an empty String as the new URL. If we set the URL to some address that is not an "active" domain name (e.g. https://absolutegarbage-sdjdjfbskdfb.com), the request for that resource fails immediately:
#Override
public boolean onBeforeResourceLoad(CefBrowser cefBrowser, CefFrame cefFrame, CefRequest cefRequest) {
if (cefRequest.getResourceType().equals(CefRequest.ResourceType.RT_IMAGE)) {
cefRequest.setURL("https://yghjbnbk.com");
System.out.println("LOL!");
}
return false;
}
As you can probably guess, this still is not the best solution. Please post an answer or comment if someone has found a better solution.
Edit 2: Finally I have a clean working solution, thanks to user amaitland. We just have to pass a command line switch while setting the CefAppHandler. We can do that by overriding the method onBeforeCommandLineProcessing like this:
CefApp.addAppHandler(new CefAppHandlerAdapter(null) {
#Override
public void onBeforeCommandLineProcessing(String s, CefCommandLine cefCommandLine) {
cefCommandLine.appendSwitch("disable-image-loading");
}
#Override
public void stateHasChanged(CefApp.CefAppState state) {
if (state == CefApp.CefAppState.TERMINATED) System.exit(0);
}
});

Null Pointer Exception in netflix hystrix library

Recently I started working on netflix hystrix library. I created a HystrixCommand object but I get a NPE. Ideally, it shouldn't happen. Any help will be appreciated. Is it a known issue ?
Please find the stack trace :
Exception in thread "main" java.lang.NullPointerException
at com.netflix.config.ConcurrentMapConfiguration.clearConfigurationListeners(ConcurrentMapConfiguration.java:330)
at org.apache.commons.configuration.event.EventSource.<init>(EventSource.java:76)
at org.apache.commons.configuration.AbstractConfiguration.<init>(AbstractConfiguration.java:63)
at com.netflix.config.ConcurrentMapConfiguration.<init>(ConcurrentMapConfiguration.java:68)
at com.netflix.config.ConcurrentCompositeConfiguration.<init>(ConcurrentCompositeConfiguration.java:172)
at com.netflix.config.ConfigurationManager.getConfigInstance(ConfigurationManager.java:125)
at com.netflix.config.DynamicPropertyFactory.getInstance(DynamicPropertyFactory.java:263)
at com.netflix.config.DynamicProperty.getInstance(DynamicProperty.java:245)
at com.netflix.config.PropertyWrapper.<init>(PropertyWrapper.java:58)
at com.netflix.hystrix.strategy.properties.archaius.HystrixDynamicPropertiesArchaius$ArchaiusDynamicProperty.<init>(HystrixDynamicPropertiesArchaius.java:62)
at com.netflix.hystrix.strategy.properties.archaius.HystrixDynamicPropertiesArchaius$StringDynamicProperty.<init>(HystrixDynamicPropertiesArchaius.java:73)
at com.netflix.hystrix.strategy.properties.archaius.HystrixDynamicPropertiesArchaius.getString(HystrixDynamicPropertiesArchaius.java:34)
at com.netflix.hystrix.strategy.HystrixPlugins.getPluginImplementationViaProperties(HystrixPlugins.java:344)
at com.netflix.hystrix.strategy.HystrixPlugins.getPluginImplementation(HystrixPlugins.java:334)
at com.netflix.hystrix.strategy.HystrixPlugins.getPropertiesStrategy(HystrixPlugins.java:243)
at com.netflix.hystrix.strategy.properties.HystrixPropertiesFactory.getCommandProperties(HystrixPropertiesFactory.java:62)
at com.netflix.hystrix.AbstractCommand.initCommandProperties(AbstractCommand.java:204)
at com.netflix.hystrix.AbstractCommand.<init>(AbstractCommand.java:163)
at com.netflix.hystrix.HystrixCommand.<init>(HystrixCommand.java:61)
I faced similar issue, and here is how I solved it.
Hystrix -> uses archaius-core-0.4.1.jar -> which uses commons-configuration-1.8.jar
But due to jar conflicts in my current project, commons-configuration-1.3.jar is present instead of commons-configuration-1.8.jar
Unfortunately, there seems to be a bug in commons-configuration-1.3.jar in the constructor of org.apache.commons.configuration.event.EventSource (which I will explain below)
So, my suggestion is take a look into your classpath and I am sure you will find commons-configuration-1.3.jar. If so, just make sure you have the correct commons-configuration-1.8.jar. This should solve your problem!
Root Cause:
com.netflix.config.ConcurrentMapConfiguration -> is a sub class of
org.apache.commons.configuration.AbstractConfiguration -> which is a sub class of org.apache.commons.configuration.event.EventSource
Here is the skeleton
public class ConcurrentMapConfiguration extends AbstractConfiguration {
...
private Collection<ConfigurationListener> listeners = new CopyOnWriteArrayList<ConfigurationListener>();
...
public ConcurrentMapConfiguration() {
...
}
...
#Override
public void clearConfigurationListeners() {
listeners.clear(); // Here is the null pointer exception
}
...
}
But in EventSource (commons-configuration-1.3.jar)
public class EventSource {
...
public EventSource()
{
clearConfigurationListeners(); // This is the culprit
}
...
public void clearConfigurationListeners()
{
listeners = new LinkedList();
}
...
}
As you clearly see in the constructor of EventSource, you see an invocation to method clearConfigurationListeners(). And this method has been overriden in subclass ConcurrentMapConfiguration. So, the subclass method will be invoked. But by this time listeners is still null, because only after super class constructor is done the subclass can start initializing its stuff. Hence the NPE.
But in EventSource (commons-configuration-1.4.jar and above) - it is fixed
public class EventSource {
...
public EventSource()
{
initListeners(); // this is good
}
...
private void initListeners() // private method... Much better! No one can override this :)
{
listeners = new LinkedList();
...
}
...
}
Hope this helps!

Java Reflection: Code runs fine in Debugger but not in "normal" running mode

I'm trying to call a static Method from an Array of Methods. This works just fine in the debugger but not in normal running mode.. Why is this?
More description in code comments below..
EDIT for easier reproduction just run this class in Debugger vs. normal Mode:
public class Stackoverflowquestion {
public static class Backautomat {
private String aktuellBackendeBrotsorte = "Butterbrot";
//Test für Statische Methoden: Brauche ich dazu auch eine Instanz für Invoke?
public static String getBezeichnung(){
return "Bezeichnung: Bester-Backautomat-Ever";
}
//Test für Methoden ohne Parameterliste
public boolean backautomat_starten(){
return true;
}
}
public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//Get all methods of class
Method[] backaudomadMethoden = Backautomat.class.getMethods();
//Get first Method of class -> I know this one is static -> see in source "Backautomat"
Method backMethod = backaudomadMethoden[0];
//Printing out Method Name: In Debugger this returns the static method name: getBezeichnung(),
//In "normal" running mode (Run -> Run as -> Java Application) it prints out the second method: backautomat_starten()
System.out.println(backMethod.getName());
//Invocation is successfull in debugger
//Invocation throws exception running in "normal" mode
System.out.println(String.valueOf(backMethod.invoke(null)));
}
EDIT exception looks like this:
backautomat_starten Exception in thread "main" java.lang.NullPointerException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.relfection.easy.example.Stackoverflowquestion.main(Stackoverflowquestion.java:31)
Consider the documentation of Class.getMethods():
…
The elements in the returned array are not sorted and are not in any particular order.
This implies that arbitrary aspects of the current JRE can have the side effect of altering the result, running in the debugger inclusive.
So if the first method in the array is not the one you expect, getting a different name than expected and producing an exception when attempting to run the instance method like a static method, are symptoms of the same wrong assumption.
https://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Method.html#invoke(java.lang.Object,%20java.lang.Object...)
This states that you call that method on the passed in defined object
String.valueOf(backMethod.invoke(null));
Here are you passing in null as the object, so you are trying to call a method on a null object.
Its similar to doing something like
Object x = null;
x.toString();
and obviously x.toString() would throw the NPE

Calling getString() in constructor in Wicket gives error

I'm having some problems with localization in wicket.
This is the code:
private String displayString;
private TextField<String> myTextField;
public myPage(DomainObject domainObject){
if(domainObject != null)
displayString = domainObject.getDisplayString();
myTextField = new TextField<String>("myTextField", new PropertyModel<String>(this, "displayString"));
if(Strings.isEmpty(displayString))
displayString = getString("mandatory"); //<- error message here
}
The problem is that calling getString in the constructor results in an error message("...This can sometimes lead to an invalid or no localized resource returned...").
I want to use a PropertyModel for the TextField since I don't want to translate the string I get from domainObject.getDisplayString(). I don't want the changes made in the TextField to affect the value in domainObject directly.
It's possible to get rid of the error message by doing this instead of getString:
if(Strings.isEmpty(displayString))
displayString = new ResourceModel("mandatory").getObject(); //<- no error message
To my understanding, this is the same thing as calling getString (you just hack away the warnings, but the problem still exist).
A solution i thought of is this:
#Override
protected void onAfterRender() {
super.onAfterRender();
if(Strings.isEmpty(displayString))
displayString = getString("mandatory"); //<- no error message
}
Does anyone see a problem with this solution? Maybe I'm not thinking "wickety" enough?
Calling getString() requires the component to be inside a component hierarchy, where it can access it's parent to have the chance to fall back to properties defined there or further up in the tree. This isn't possible inside the component's constructor (as you add it to it's parent at a later point). Wicket 1.5 introduces the onInitialize function for these operations. With Wicket versions prior to this, there is an easy way to emulate this behaviour:
In your base component and page define a non-final empty method as
protected void onInitialize() {}
and add this to the onBeforeRender method:
protected void onBeforeRender() {
...
if (!hasBeenRendered()) {
onInitialize();
}
...
}
Then you can use an overridden onInitialize() method in any of your components to deal with stuff that has to wait until the component hierarchy is established.
What about a reusable behavior:
public class MandatoryBehavior extends AbstractBehavior {
public void onComponentTag(Component component, ComponentTag tag) {
if (((AbstractTextComponent)component).isRequired() && Strings.isEmpty(tag.get("value"))) {
tag.put("value", component.getString("mandatory"));
}
}
}
You'd have to check submitted values in a validator though.
HTML5 placeholders are even nicer.

Is this typically how Java interfaces are used to set up event handlers, and are there hidden drawbacks to this approach?

Hey all, I'm still relatively new to Java, and looking for a sanity check.
I've been studying this Java port of Cocos2D and noticed that the CCLayer class has built-in hooks to the Android native touch events. That's great, but what I'd really like is for objects like CCSprite to directly respond to touch events without having to listen for those events in the layer and iterate through all the children to find which ones happen to intersect the event's x/y coordinates. So I figured that this would be the perfect chance to test my understanding of how to set up some event handlers and make a subclass of CCSprite that actually listens for touches without needing to go through CCLayer to know about it. Furthermore, I wanted to be able to assign different behaviors to different CCSprite instances on an ad-hoc basis without explicitly subclassing further, much like Android Buttons don't need to be subclassed just to give them a handler for their touch events.
This is what I came up with on a first pass:
// My touch interface for all touchable CCNode objects.
package com.scriptocalypse.cocos2d;
public interface ITouchable {
boolean onCCTouchesBegan();
boolean onCCTouchesEnded();
boolean onCCTouchesMoved();
}
And now the class that uses the ITouchable interface for its callbacks...
public class CCTouchSprite extends CCSprite implements CCTouchDelegateProtocol {
protected ITouchable mTouchable;
public void setTouchable(ITouchable pTouchable){
mTouchable = pTouchable;
boolean enable = mTouchable != null;
this.setIsTouchEnabled(enable);
}
public void setIsTouchable(boolean pEnabled){
// code to enable and disable touches snipped...
}
/////
// And now implementing the CCTouchDelegateProtocol...
/////
public boolean ccTouchesBegan(MotionEvent event) {
Log.d("hi there", "touch me");
if(mTouchable != null){
mTouchable.onCCTouchesBegan();
}
return CCTouchDispatcher.kEventHandled; // TODO Auto-generated method stub
}
public boolean ccTouchesMoved(MotionEvent event) {
if(mTouchable != null){
mTouchable.onCCTouchesMoved();
}
return CCTouchDispatcher.kEventIgnored; // TODO Auto-generated method stub
}
public boolean ccTouchesEnded(MotionEvent event) {
Log.d("hi there", "not touch me");
if(mTouchable != null){
mTouchable.onCCTouchesEnded();
}
return CCTouchDispatcher.kEventIgnored; // TODO Auto-generated method stub
}
}
And finally, instantiate the class and implement the interface...
final CCTouchSprite sprite = new CCTouchSprite(tex);
sprite.setIsTouchEnabled(true);
sprite.setPosition(CGPoint.ccp(160,240));
sprite.setTouchable(new ITouchable(){
#Override
public boolean onCCTouchesBegan() {
Log.d("SWEET SUCCESS", "I got a touch through my interface!");
return true;
}
#Override
public boolean onCCTouchesEnded() {
Log.d("SWEET SUCCESS", "You stopped touching my interface!");
sprite.runAction(CCRotateBy.action(1, 360));
return false;
}
#Override
public boolean onCCTouchesMoved(){
Log.d("SWEET SUCCESS", "You moved the touch");
return false;
}
});
So all of this works. The subclass does successfully register with the Cocos2D touch dispatcher, which successfully calls those ccTouches functions and pass them MotionEvents, which in turn call my Interface functions if the interface has been instantiated.
Is this the "proper" way to do it (Define "it" as you see fit, ranging from using Interfaces to create event handlers to working with Cocos2D, to writing Java at all)? Are there drawbacks to this that I'm not aware of? Is this somehow worse for performance than iterating through all the CCNode objects that are children of CCLayer? If so, how can that possibly be?
I think you have got the basics for setting up a listener right. There are some things I would change though.
First, the setter setIsTouchable. It's weird. You need a listener object to pass touch events to right? So what is this setter going to do when you pass it true (as your example does)? You snipped the code, but setting a boolean field to true does not seem right here as it would put the sprite object in an inconsistent internal state. I would just drop that setter. The getter can just evaluate whether mTouchable is assigned or null.
Second, why limit yourself to one listener? Change mTouchable to mTouchables, being a list of ITouchables. Then change setTouchable to addTouchable and possibly add removeTouchable and clearTouchables methods. This way you can add multiple listeners for different behaviors having to respond to the same events. This is how most other event systems work as well. You then just change isTouchable to check whether the list is empty or not.
scriptoclypse... I really am not completely understanding your question, but you have not had any response and yes interfaces and events are very similar. At this level I can only respond in C#.

Categories