I get this error:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at onlineShopExamen.Client.remove(Client.java:30)
at onlineShopExamen.Main.<init>(Main.java:17)
at onlineShopExamen.Main.main(Main.java:23)
My code is this:
public void remove(){
Iterator<Product> iter = lijstProducten.iterator();
while(iter.hasNext()){
Product movie = iter.next();
lijstProducten.remove(movie);
}
}
Where Product is a list of products (movies in this case)
Using this:
public void remove(){
Iterator<Product> iter = lijstProducten.iterator();
while(iter.hasNext()){
iter.remove();
}
}
Doesn't work either
That gives me this error:
Exception in thread "main" java.lang.IllegalStateException
at java.util.ArrayList$Itr.remove(Unknown Source)
at onlineShopExamen.Client.remove(Client.java:30)
at onlineShopExamen.Main.<init>(Main.java:19)
at onlineShopExamen.Main.main(Main.java:25)
EDIT FIXED
This works:
public void remove(){
Iterator<Product> iter = lijstProducten.iterator();
while(iter.hasNext()){
iter.next();
iter.remove();
}
}
that's what's called a conservative iterator: as soon as the underlying container is modified any iterator pointing to that container is invalidated (that's what the ConcurrentModificationException means).
there is a Iterator.remove method. use it.
public void remove(){
Iterator<Product> iter = lijstProducten.iterator();
while(iter.hasNext()){
iter.next();
iter.remove(); // removes previous item
}
}
which you can probably (assuming lijstProducten is a List) also write as mentioned by Ankit
public void remove(){
lijstProducten.clear();
}
In addition to Beyeler's answer. As I see from your code, your remove method is clearing the whole list.
I would suggest you to use the method myList.clear(); to remove all the elements from a list instead of making your own method.
Try iter.remove() instead of lijstProducten.remove(movie). You cannot modify the list youre iterating but theres remove method in Iterator that will do it for you.
Related
Could anyone please help with understanding of the following. Here is the code:
public class GoLoose {
public static void main(String[] args) {
try{
new Lost();
}catch (Throwable e){
e.printStackTrace();
}
new Lost();
}
}
class Lost{
final static int i = 1 / 0;
}
the result will be like:
java.lang.ExceptionInInitializerError
at test_linkage.GoLoose.main(GoLoose.java:7)
Caused by: java.lang.ArithmeticException: / by zero
at test_linkage.Lost.<clinit>(GoLoose.java:17)
... 1 more
Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class test_linkage.Lost
at test_linkage.GoLoose.main(GoLoose.java:11)
As far as I can understand, it loads Lost's class file, then compiles and then tries to initialize static variable 'i' of the the Lost class - it fails with ArithmeticException wrapped by ExceptionInInitializerError. We catch it and only print and go further. Next, while trying to create a new instance of Lost again, it throws NoClassDefFoundError like it doesn't try to initialize Lost class now. And that is what I don't understand-why it don't try again? Why there is no ArithmeticException again?
It's said in the spec under 5.5. Initialization part: "If the Class object for C is in an erroneous state, then initialization is not possible. Release LC and throw a NoClassDefFoundError."
May it be that this is exactly what happens in my code? Like, after first attempt of initialization, if it goes wrong, class gets some "erroneous state" and having this state the class will never be eligible for further attempts of initialization. But then, what exactly is this state and where is it stored?
Thanks!
Assume I have a class C that holds resources that need to be closed as member variables.
public class C {
private ClosableResource1 closableResource1;
private ClosableResource2 closableResource2;
.....
public C(){
closableResource1 = new ClosableResource1();
closableResource2 = new ClosableResource2();
.....
// some logic that can fail
}
close(){
closableResource1.close()
closableResource2.close()
.....
}
}
If the constructor succeeds I can be sure that close() will be called eventually by some entity manager and all the resources will be freed.
But how can I make sure I close the resources when the constructor fails? The failure can happen because I have additional logic in the constructor that can throw exception or I get some RuntimeException outside of my control?
Some things I though of:
Wrapping the constructor body with a try-catch block. Then, assuming I have a lot of closable members I'll have to have a big if statement in the catch block checking which resources were already initializing and only close them.
Offloading the ClosableResources creation to some init() function. Then I would have to make sure init() succeeded every time I try to use the object.
Is there some elegant solution? Or is this much more implementation specific then that?
You can do something like below:
public class C {
private List<AutoCloseable> closableResources = new ArrayList();
private ClosableResource1 closableResource1;
private ClosableResource2 closableResource2;
.....
public C() {
closableResource1 = new ClosableResource1();
closableResources.add(closableResource1)
closableResource2 = new ClosableResource2();
closableResources.add(closableResource2);
.....
try {
// some logic that can fail
} catch(Exception e) {
close();
}
}
close(){
for (AutoCloseable closableResource : closableResources) {
if (closableResource != null) {
closableResource.close();
}
}
}
}
Surrounding your code with try-catch and closing all your resources in catch is the correct solution here. Also read about method finalize() (Here is one tutorial). In general, I would recommend one method that cleans up all the resources (like you suggested method close(), I would call it though cleanup()) and call that method in your catch section and in your finalize() method
I asked and answered a very similar question here. It is very important that a constructor either succeeds or fails completely i.e. leaving no resources open. In order to achieve that I would follow each resource creation statement by a try-catch block. The catch block closes the resource and rethrows the exception so it is not lost:
public C() {
closableResource1 = new ClosableResource1();
closableResource2 = new ClosableResource2();
try {
// .....
// some logic that can fail and throw MyCheckedException or some RuntimeException
} catch (RuntimeException | MyCheckedException e) {
try {closableResource1.close();} catch (Exception ignore) {}
try {closableResource1.close();} catch (Exception ignore) {}
throw e;
}
}
If creating a resource can fail you need nested try-catch blocks as demonstrated here.
Here's a wild idea: create a class called something like DefusableCloser (that you can "defuse", like an explosive device being made safe):
class DefusableCloser implements AutoCloseable {
boolean active = true;
final AutoCloseable closeable;
DefusableCloser(AutoCloseable closeable) {
this.closeable = closeable;
}
#Override public void close() throws Exception {
if (active) closeable.close();
}
}
Now you can use this in a try-with-resources block:
c1 = new CloseableResource();
try (DefusableCloseable d1 = new DefusableCloseable(c1)) {
c2 = new CloseableResource();
try (DefusableCloseable d2 = new DefusableCloseable(c2)) {
// Do the other stuff which might fail...
// Finally, deactivate the closeables.
d1.active = d2.active = false;
}
}
If execution doesn't reach d1.active = d2.active = false;, the two closeables (or one, if the exception was in creating the second resource) will be closed. If execution does reach that line, they won't be closed and you can use them.
The advantage of doing it like this is that the exceptions will be correctly handled.
Note that the ordering is important: don't be tempted to create the two CloseableResources first, then the two DefusableCloseables: doing that won't handle an exception from creating the second CloseableResource. And don't put the creation of the CloseableResources into the TWR, as that would guarantee their closure.
For closing the resources in your class' close() method, you can also use try-with-resources to ensure that both resources are closed:
try (c1; c2) {}
You don't actually have to declare a new variable in the TWR syntax: you can just effectively say "close the resource for this existing variable afterwards", as shown here.
guys. Today I have done my custom realization for WebDriverEventListener. I need only onException() method which will create screenshot. But I got problem because I am using fluent wait.
new FluentWait<>(webDriver)
.withTimeout(Duration.ofSeconds(10))
.pollingEvery(Duration.ofMillis(500))
.ignoring(NoSuchElementException.class)
.until(someCondition)
So, finally, I have got screen for each ignoring(NoSuchElementException.class) - 20 screenshots for 1 fail ))). Had somebody the such problem or had someone resolve it?
when you use .ignoring(NoSuchElementException.class) you don't avoid that the exception is raised, you are just ignoring that exception. What is happening is that the exception is being raised by your FluentWait, but it is ignored (when you declare .ignoring(NoSuchElementException.class)).
You have three options here:
Capture the screen at the end of your test if the test failed [preferred].
Have a Try-Catch wherever you are using your FluentWait or any other Selenium code.
Use reflection to avoid capture when the event is raised from the method that implements the FluentWait.
This is an idea after what we have discussed:
private void ExceptionThrown(object sender, WebDriverExceptionEventArgs e)
{
if (e.ThrownException is NoSuchElementException)
{
// Get the stack trace from the current exception
StackTrace stackTrace = new StackTrace(e.ThrownException, true);
// Get the method stack frame index.
int stackTraceIndex = stackTrace.FrameCount - 1;
// Get the method name that caused the exception
string methodName = stackTrace.GetFrame(stackTraceIndex).GetMethod().Name;
if(methodName != "MyFindElement")
{
TakeSceenshot();
}
}
else
{
TakeSceenshot();
}
}
// This is an extension method of the DriverHelper interface
public IWebElement MyFindElement(this IWebDriver driver, By by, int timeOut = 0)
{
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeOut));
wait.IgnoreExceptionTypes(typeof(NoSuchElementException));
// I wait until the element exist
IWebElement result = wait.Until(drv => drv.FindElement(by) != null);
// it means that the element doesn't exist, so we throw the exception
if(result == null)
{
MyPersonalException(by);
}
}
// The parameter will help up to generate more accurate log
public void MyPersonalException(By by)
{
throw new NoSuchElementException(by.ToString());
}
This probably require changes in EventFiringWebDriver, because this class is without WebDriverWait instance and events for them. If you want avoid it, create bool variable in your EventFiringWebDriver extended class and check this value in your OnException like:
protected void OnException(WebDriverExceptionEventArgs e) {
if (IsWaitHandler)
return;
Your actions...
}
but this is not perfect solution.
Hello everyone I'm tying to create a method that receives a list of string values and returns the list in reverse. The for loop is supposed to traverse the values in reverse order, starting with the last element. I'm getting an error message when I try to call the method in the main method, I don't know what argument to pass. Here is my code.
enter code here :import java.util.*;
public class ThisList
{
public static void main (String[] args)
{
list(ArrayList<String> words);
}
public static ArrayList<String> list(ArrayList<String> words)
{
ArrayList<String> phrase =new ArrayList<String>();
words.add("before");
words.add("gone");
words.add("has");
words.add("man");
words.add("no");
words.add("where");
words.add("go");
words.add("bodly");
words.add("To");
for(int i= words.size()-1; i>= 0; i--)
{
phrase.add(words.get(i));
}
return phrase;
}
}
Your problem lies in how you are calling your list() function in main, specifically in how you are improperly sending in your argument. You should not declare/initialize an object in the calling of a function. It is syntactically incorrect, plus how would you access it afterwards? Even if it was possible to declare an object in the calling of the function, the words array is also uninitialized when you are trying to use it. Also, your function list() is returning an ArrayList. You are not setting an ArrayList in your main() function to be set to the returning ArrayList(phrase) from list().
I would advise looking over Object-Oriented programming basics and a few beginner Java tutorials so you can get a better understanding to be able to solve this kind of problem on your own.
http://docs.oracle.com/javase/tutorial/java/concepts/
Below is the code you posted, with the proper way to call your function. If this is what you need, do not forget to upvote and select this answer as the correct one! (Upvote by pressing the up arrow next to the post, and accept answer by clicking the checkmark next to the post so that it turns green).
import java.util.*;
public class ThisList
{
public static void main (String[] args)
{
ArrayList<String> words = new ArrayList<String>();
ArrayList<String> phrase_returned = list(words);
}
public static ArrayList<String> list(ArrayList<String> words)
{
ArrayList<String> phrase =new ArrayList<String>();
words.add("before");
words.add("gone");
words.add("has");
words.add("man");
words.add("no");
words.add("where");
words.add("go");
words.add("bodly");
words.add("To");
for(int i= words.size()-1; i>= 0; i--)
{
phrase.add(words.get(i));
}
return phrase;
}
}
I need to be able to add items to a listbox inside of a thread. Code is below:
1. ref class Work
2. {
3. public:
4. static void RecieveThread()
5. {
6. while (true)
7. {
8. ZeroMemory(cID, 64);
9. ZeroMemory(message, 256);
10. if(recv(sConnect, message, 256, NULL) != SOCKET_ERROR && recv(sConnect, cID, 64, NULL) != SOCKET_ERROR)
11. {
12. ID = atoi(cID);
13. String^ meep = gcnew String(message);
14. lbxMessages->Items->Add(meep);
15. check = 1;
16. }
17. }
18. }
19. };
I get the error
Error: a nonstatic member reference must be relative to a specific object on line 14. Is there any way to get it to let me do that? Because if I try to use String^ meep; outside of that Thread it doesn't contain anything. It works PERFECT when I use it within the thread but not outside of it. I need to be able to add that message to the list-box. If anyone can help I would appreciate it.
You don't show how lbxMessages is defined, but I'm going to assume that it's a non-static data member in the same class. If that's the case, then you need to specify which object you want to access lbxMessages on. The simplest way would be to switch the RecieveThread method to be non-static, then you can access this->lbxMessages.
You didn't say which windowing toolkit you're using, but you probably will need to Invoke back onto the UI thread in order to edit the control.
One way is using System::Thread with a ParameterizedThreadStart delegate, which let you pass objects, in this case lbxMessages.
ParameterizedThreadStart^ threadCallback;
threadCallback = gcnew ParameterizedThreadStart(&Work::ReceiveThread);
Thread^ recvThread = gcnew Thread( threadCallback );
recvThread->Start( lbxMessages );
Your static method for running the thread:
static void RecieveThread(Object^ state)
{
ListBox^ lbxMessages = (ListBox^)state;
//...code
}
But.. . there is another problem. Assuming ListBox is a Win32 control, you can make changes in control only from the thread which it was created. So every time you insert a ListBox item, it must be done from the UI's thread. One way is using a SynchronizationContext object.
// Start the thread
array<Object^>^ args = gcnew array<Object^>(2){
lbxMessages,
SynchronizationContext::Current
}
recvThread->Start( args);
Thread method should be something like this:
static void RecieveThread(Object^ state)
{
array<Object^>^ args = (array<Object^>^)state;
ListBox^ lbxMessages = (ListBox^)args[0];
SynchronizationContext^ ctx = (SynchronizationContext^)args[1];
//...code
String^ meep = gcnew String(message);
ctx->Send(gcnew SendOrPostCallback(&Work::SafeListBoxInsert),
gcnew array<Object^>(2){lbxMessages, meep}
);
}
You will need another method to be called from UI's thread and make the changes.
ref class Work{
//...other methods
static void SafeListBoxInsert(Object^ state)
{
array<Object^>^ args = (array<Object^>^)state;
ListBox^ lst = (ListBox^) args[0];
String^ item = (String^) args[1];
lst->Items->Add(item);
}
}