Yevgeni Duvenage

Greenhorn
+ Follow
since Sep 11, 2017
Cows and Likes
Cows
Total received
1
In last 30 days
0
Total given
0
Likes
Total received
1
Received in last 30 days
0
Total given
1
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Yevgeni Duvenage

Tim, thank you for the reply.

I have indeed gathered that scriptlets have been obsolete for a long time, however for my task I need to follow the textbook's instructions - yes it is an old book.

I will review the suggested for my own knowledge, but could you still let me know how I can achieve the asked using scriptlets in the JSP?

Thanks.
3 years ago
JSP
Good day, all.

I have the following setup:

- A JSP that outputs an HTML form to browser, then when one of the buttons is clicked after user enters an amount in the
 text field,
- The data is sent to a servlet that performs certain calculations and sends result data back to the JSP.
- The JSP then shows the result data and keeps running so user can make more iterations using the program.

I am trying to code the JSP such that when it runs, it first checks for existence of 2 session attributes, "balance"
and "formattedBal". If these attributes do not exist (meaning this is the very first time running the JSP after the
user just hit its URL address), the JSP execution must create and assign these session attributes. If these attributes
do exist (meaning this was not the initial launch of the JSP but a consequent one, with servlet having reverted the user
to the JSP and sent result data, hence non-null session attributes to it), the JSP must simply execute the HTML output,
showing the values of said session attributes in appropriate coded places.

The following is the code of the JSP:



The problem is, I'm getting an error that points to line 11 - the <% tag. Whether I use a function or not, the error
remains and reads exactly as follows:

HTTP Status 500 -

type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
org.apache.jasper.JasperException: Unable to compile class for JSP

An error occured at line: 11 in the jsp file: /bank.jsp
Generated servlet error:
Syntax error on token "=", != expected

org.apache.jasper.compiler.DefaultErrorHandler.javacError(DefaultErrorHandler.java:84)
org.apache.jasper.compiler.ErrorDispatcher.javacError(ErrorDispatcher.java:328)
org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:397)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:288)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:267)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:255)
org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:556)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:296)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:295)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:245)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)


I have been researching this and related errors, but to not much avail.

What makes no sense is the error states that I am using an = sign, but it expects an != combination, while as you see
line pointed to there is never an = sign in the first place.

I'm new to Java and it is possible this is a simple mistake somewhere, could you please help to identify it?

I need to use scriptlets in the JSP whenever I need to utilize "standard" Java commands.

Also, if the described and coded way to check for existence of these session attributes and their conditional
assigning is not correct, please advise how I would better achieve this.

Thank you very much!
3 years ago
JSP
Dave, thank you very much, you are totally correct.

The problem was indeed that one browser (Chrome in my case) shared the session between all running tabs. Shared the cookie, as you explained. I tested now with rather running the servlet in Chrome and another in Internet Explorer and they ran perfectly independently from each other, not affecting each other's "balance" variable.
3 years ago
Good day, all.

I have a servlet, in which I have local variables declared, initiated and assigned to session attributes.

I need the servlet to be thread-safe, such that multiple browser windows on same computer can have the servlet running and you could perform calculations in each window, but such that the operations in the various threads would not influence each other, that is, that the account balance variable was not shared among the threads, causing inconsistent states of it for any thread at any time.

The below is my code:

   

Now, what happens instead is, when using multiple threads (browser windows running the servlet), the balance that one thread overwrites, becomes the balance that another thread reads. Which is of course incorrect. I need each simultaneous thread to have its own copy of this variable for consistent results.

As far as I know, unlike storing the balance as a class (instance) variable, storing it as local and assigning to session attribute is thread-safe. But if that is so, why do the threads update one another's variable? What is coded incorrectly?

Thanks a lot!
3 years ago
I read the article. It points out that (for some reason) if one method that is synchronized, is being locked for use by some thread, then all other methods that are coded as synchronized are locked as well. That does not make sense to me, why would the program only be able to run one method at a time instead of being able to run any of its methods, depending on what simultaneous threads require?

I understand that "balance", as it is, cannot be locked on as it is not an object. I understand also that synchronized methods lock onto the class.

The article also shows examples of code in which an Object is created within the class and is used as monitor, or, things like int data are defined not as simple int but as int arrays, so that you could create and object of them and then lock onto that object for synchronization.

Should I then attempt likewise with my double "balance" variable? Declare it instead as an array and set it as object, then lock directly onto it in synchronization blocks?
3 years ago
Hey, Dave.

Then I really need to confirm something:

Say, you have methods A, B and C which do different things but all refer to and modify "balance" variable.
Say, only method A is synchronized, meaning that while it executes operating on "balance", the other 2 have to wait. That is if all works as must.
Do these other 2 methods need to be synchronized for the above to happen?

I thought that as long as one method keeps a lock on the variable (is synchronized), that already means that any other methods, synchronized or not, will HAVE to wait for access to the variable. Or is this wrong understanding and you have to "mark" each method as synchronized so that Java knows that all these (marked synchronized) methods are the ones that may possible try interfering with one another and therefore these are the ones that will wait on one another?

So in this context, my thinking was that even though showBalance() is not synchronized but addToBalance() is, if addToBalance() executes, and thus has the lock on "balance", it implies that showBalance() will have to wait for access to "balance". I am unclear on this...

Then about what you said of me locking on the servlet instead of the variable, when I synchronize a method - how to lock on the variable then? Use block of code? But then what do I do to make the variable an object or how do I lock onto it?

What is more absurd then about this exercise, is that the book tells me to "...use synchronized blocks of code or METHODS". It's hard to believe the possibility of there being so many errors in a textbook all in one task instruction?

This really is confusing...
3 years ago
Hey, guys.

Firstly, Stephan says I am not locking on the servlet, while Dave says I am locking on the servlet. Contradiction here, so am I or am I not?

Also, you are saying that by synchronizing a whole method I lock on the servlet instance - what exactly do you mean?

You also say that because the showBalance() method is not synchronized, that is why I am having the problem we're discussing, but isn't synchronization only needed when trying to modify and overwrite a variable? I mean the showBalance() method only reads the balance variable, then formats it for display. It does not change its value. So then it's only the addToBalance() and subtractFromBalance() methods (which actually change the balance variable) that need to be synchronized.

But again, I tried synchronizing methods and this is not working, and I also tried synchronizing blocks of code containing operations with variable "balance" - so say instead of synchronizing the whole addToBalance() method, I would synchronize only inside it the part that refers to and overwrites "balance". But in the case of synchronizing just a block of code, how exactly do I lock onto it?

"balance" is not an object, but a double, so I can't use . How would I do this? And why should synchronizing on block of code instead of whole method make any difference?

Sorry, but being rather new to Java, I'm still trying to understand things that veterans here of course know backwards.

Thanks.
3 years ago
Stephan, Dave, the following is the current code I have:



I will try to clarify what I expect as the result:

1) 2 threads (browser windows) of servlet are open. Servlet is in initial state with variable "balance" at zero.
2) In one thread I type an amount and click "Deposit", which, by the code you see, should first sleep for 10 seconds, then perform the actual addition and overwriting of the balance.
3) Switching rapidly to the other thread (before the 10 seconds elapse), I click "Balance" and trigger the method that gets current balance number, formats it and renders to screen.
    - because the addToBalance() method is synchronized and also should run for at least 10 seconds, I expect the second thread to NOT show the updated balance unless 10 seconds have passed. Because as we are discussing,
       the thread must wait for the first thread to release the lock on the "balance" variable.
    - however, the second thread does not wait at all and displays the new balance instantly -> as if no synchronization and/or sleep() were ever used in the code.

Like was said in this post, the instance variable "balance" is shared among threads, so synchronizing on it should cause other threads to wait while the first finishes using it, but as you can see, this does not happen.
3 years ago
The next task I am to do indeed instructs to remove instance variables and use session attributes, with which no synchronization is needed and multiple threads will not interfere with one another.

But the current task in discussion instructs me to synchronize access to this instance variable. Is there then really no way to achieve this?
3 years ago
Thanks, Dave.

The sleep() is now still inside the addToBalance() method, but is coded before the lines that add entered amount to the balance variable, so:

...addToBalance()
{
    Thread.currentThread().sleep()...                // First delay the addition procedure by 10 seconds.
    balance = balance + amount...                   // Then add to the balance.
}

It does make sense what you say about rather using session attributes for multi-user servlets, and thing is my next task (modification to this servlet) will be just that. But as per instruction of this task under discussion here, I am not to use session procedures yet. So I am trying to figure out why the synchronization doesn't work as intended.

I need to ask - when one thread waits on another to finish a certain process, how would this look in the browser? Would it be a blank screen in the waiting thread, with a "please wait" mouse cursor, or should everything refresh/load as usual, except that values being locked will not be updated by the other thread that tries to interfere, until the first thread finishes with its synchronized process?
3 years ago
Dave.

Regarding the location of the sleep() code-line within the addToBalance() synchronized method:

I did consider your point before, and after I posted the code you saw, I actually swapped the order of code to add to and overwrite balance and perform the delay. It made no difference.
3 years ago
Dave, as to why 2 threads would refer to the same balance simultaneously - since my understanding as stated above that multpile threads (instances of servlet) share this common variable "balance", it means that in the possible scenario of more than 1 user using the servlet at the same time, those multiple uses might also be such that more than 1 user attempts to use same servlet function (coded method) at same time, hence requiring simultaneous access to the "balance" variable.
3 years ago
Hey Dave.

What you just said is also my suspicion, since I learned about instances and threads. Maybe you could correct me, but evidently I'm misunderstanding servlet instances and threads:

I have read from many sources and understood it as: there is one servlet .class file. But multiple users on multiple computers can hit the URL to open the servlet and use the servlet. Then it is said that each user is utilizing an instance of the servlet.

At the same time I read regarding similar problems that each thread uses its own copy of the servlet class and instance variable. According to this, then it makes sense that if each thread creates its own copy of the "balance" variable, which it then proceeds to use -> there is then never a condition where one copy of "balance" is accessed by more than one thread.

Now, the above information is conflicting. Could you please help to clarify where I misunderstand?

You noted that the way the servlet is written is for a single user, yet this is how the textbook instructs to code the servlet: to use an instance variable for the balance. Then you must test for yourself what happens when multiple threads use this servlet simultaneously and change the variable, and the change reflects on all threads' "balance".

How am I to code this then, using an instance variable, for multiple users?
3 years ago
So in the above example. the second thread should show $0 if you click "Balance" before 10 seconds elapse. However, it already shows $5000 - as was added in thread #1. But there is no delay.
3 years ago
Hey, guys. The following is the entire code of my servlet - there are also comments for most actions so I think the code explains itself well.



You will see in the method that adds the entered amount to the balance, there is the delay timer (sleep) coded so as to keep the method lasting for 10 seconds and be able to test what happens when 2 threads try to refer to the balance variable simultaneously.

To answer the question of what I expect the servlet to do upon execution of 2 (or more) threads:

- Surely if the method that adds to balance, running the sleep delay, causes the itself to execute for at least 10 seconds, this means that if another thread executes any operation with this shared instance variable "balance" before those 10 seconds elapse, this other thread should not see the updated balance variable yet. To put it into a testing example:

1) I open 2 threads of the servlet in the browser.
2) In one of them I type 5000 in the amount text box and click "Deposit". This should trigger the addition method and in this case as coded, the delay timer inside that method.
3) If I rapidly switch over to the other thread and click "Balance" (which brings up to screen the current balance), before the 10 seconds elapsed in the first thread running and completing the addition method - then the balance shown by this second thread must be what it was before the first thread had the addition method triggered, that is, the first thread's method should not yet have finished, and thus "balance" was unchanged.

What happens, though, is, if I do the above as a test, as soon as I switch over to the other thread and click "Balance", it brings up the NEW balance, meaning the first thread instantly added and overwrote the variable, without delaying by 10 seconds.

I did test the delay code syntax in another program - it works as should. Hence I think there is an issue with how I use synchronization.
3 years ago