Friday, October 11, 2013

Eclipse Content Assist

So last week, as far as I know, no changes were made to my machine, no updates were installed in eclipse and nothing was changed overall on my system, but Friday morning when I started up eclipse the content assist would show an error window and wouldn't assist me anymore with development.
The error says, "The 'org.eclipse.jdt.ui.JavaAllCompletionProposalComputer' proposal computer from the 'org.eclipse.jdt.ui' plug-in did not complete normally. The extension has thrown a runtime exception.
When I look in the .metadata/.log file I see the following stack traces:

!ENTRY org.eclipse.ui 4 0 2013-10-11 11:38:28.802
!MESSAGE Unhandled event loop exception
!STACK 0
java.lang.ClassCastException: org.eclipse.jdt.internal.core.SourceType cannot be cast to java.lang.String
at org.eclipse.jdt.internal.core.JavaModelManager.secondaryTypesSearching(JavaModelManager.java:4579)
at org.eclipse.jdt.internal.core.JavaModelManager.secondaryTypes(JavaModelManager.java:4438)
at org.eclipse.jdt.internal.core.NameLookup.findSecondaryType(NameLookup.java:591)

!ENTRY org.eclipse.jdt.ui 2 0 2013-10-11 11:38:29.270
!MESSAGE The 'org.eclipse.jdt.ui.JavaAllCompletionProposalComputer' proposal computer from the 'org.eclipse.jdt.ui' plug-in did not complete normally. The extension has thrown a runtime exception.
!STACK 0
java.lang.ClassCastException: org.eclipse.jdt.internal.core.SourceType cannot be cast to java.lang.String
at org.eclipse.jdt.internal.core.JavaModelManager.secondaryTypesSearching(JavaModelManager.java:4579)
at org.eclipse.jdt.internal.core.JavaModelManager.secondaryTypes(JavaModelManager.java:4438)
at org.eclipse.jdt.internal.core.NameLookup.findSecondaryType(NameLookup.java:591)
at org.eclipse.jdt.internal.core.NameLookup.findType(NameLookup.java:697)

!ENTRY org.eclipse.jdt.ui 4 2 2013-10-11 11:38:29.425
!MESSAGE Problems occurred when invoking code from plug-in: "org.eclipse.jdt.ui".
!STACK 0
java.lang.ClassCastException: org.eclipse.jdt.internal.core.SourceType cannot be cast to java.lang.String
at org.eclipse.jdt.internal.core.JavaModelManager.secondaryTypesSearching(JavaModelManager.java:4579)
at org.eclipse.jdt.internal.core.JavaModelManager.secondaryTypes(JavaModelManager.java:4438)

!ENTRY org.eclipse.jdt.ui 4 0 2013-10-11 11:38:29.427
!MESSAGE Error in JDT Core during AST creation
!STACK 0
java.lang.ClassCastException: org.eclipse.jdt.internal.core.SourceType cannot be cast to java.lang.String
at org.eclipse.jdt.internal.core.JavaModelManager.secondaryTypesSearching(JavaModelManager.java:4579)
at org.eclipse.jdt.internal.core.JavaModelManager.secondaryTypes(JavaModelManager.java:4438)
at org.eclipse.jdt.internal.core.NameLookup.findSecondaryType(NameLookup.java:591)
at org.eclipse.jdt.internal.core.NameLookup.findType(NameLookup.java:697)


I don't know what they mean and I can't find anything online to solve the problem. The work around I've found is to delete the following folder:
<workspace>/.metadata/.plugins/org.eclipse.jdt.core

Then the next time I start eclipse content assist works.

Tuesday, July 23, 2013

No database temp table needed

In the application I work on we allow users to upload photos when they create a work assignment. Those photos are getting stored in a temp table in the database so that as the form for creating assignments is reloaded we have a record of the photos that have been uploaded. I don't know why we do it this way, but recently the database team asked us to stop using that table so they could remove it and stop maintaining it. The reason it's an issue is because someone can upload files for an assignment and then never send the assignment. When that happens, being a web app, it's difficult on the server to recognize that the user left the page without finishing it, so those files become orphaned entries in the table which the database team has to clean up.

So my job was to find a way to maintain that file information in the session instead of in the database. Initially I thought it would be simple to just store the files in an object in the session, but as I started working on that I realized it would need to be cleared when a new assignment was started. Initially I thought oh that's easy, I'll just clear the temp files anytime we hit the code path that gets hit when the assignment is started, unfortunately that code path is hit when the page is reloaded after uploading a file. So my next thought was that instead of storing directly to the session I could use the object that represents the assignment and just count on that resetting the list when a new assignment is started. That seems to be working great.

This solution isn't ideal but it gets the job done. The reason I say it's not ideal is because I now have boiler plate code in several locations to get the assignment object, update it, then store it back in the session. I think the direction we want to move as we have time in the future is some kind of managed session object that moves the boiler plate stuff into a function I can call. For now though what I have gets the job done and it's fairly simple to deal with.

Friday, February 22, 2013

Cannot call sendRedirect() after the response has been committed

So for the past few months I've noticed the following error on one page in our system: Cannot call sendRedirect() after the response has been committed
Nothing on that page that deals with the request or response has changed in the past few months and the error was only happening on my dev machine, our test and production servers worked fine, so I thought it was just my machine. The other day a colleague mentioned they were also getting the error. So we started looking into it. The java code in the page seemed fine, so for a while we were stumped. He realized that over the past few months lots of html code was put before the sendRedirect. So we moved the redirect to happen before the HTML code and our problem went away. Which reminded me, I've read somewhere that you can't have any HTML tags on a JSP page before the sendRedirect call because those tags are written to the response as they are hit, which effectively commits the response to that page making it impossible to forward to another page.

Lessons learned: Don't use a JSP page as a servlet or you will have weird bugs that only make sense when you view the generated code; don't forget HTML on a JSP commits the response.

Wednesday, January 9, 2013

Cookie fun

Yesterday I ran into a problem while testing where my machine wasn't getting the correct localized strings for the french language. After lots of debugging we found that the localization is dependent on a locale set in a cookie that every user is supposed to have which wasn't getting created on my machine. Looking at the code we couldn't see any reason why it wasn't working on my machine but was working on another developer's machine. After some more debugging we found that when the cookie is created it's domain is explicitly set. Since I was accessing the site from my local machine the domain I was using didn't match the domain of the cookie. So, I modified my hosts file so that localhost mapped to the same domain as the cookie, and now all the localized strings work correctly, because the cookie is created and the locale is stored in it.

Tuesday, January 8, 2013

Page encoding issues

Today I got a bug assigned to me that had to do with how data was being sent in post requests. On the page a user could enter text in several fields, if they entered ŽŒŸ Š†€ƒaniežœš and submitted it everything on the page and subsequent pages worked fine. If however the user used these characters: ëïéâäîü they would be converted to question marks. My dilemma is that only a month ago I made a whole bunch of changes to get that first set of characters to work and I didn't want to make all the same changes again to get the new set to work. I thought (more like prayed) it had to be something simple like page encoding. Long story short I fixed the problem with about 10 lines of code. I made sure each JSP that was getting hit though the submit process had it's character set and page encoding set to UTF-8. Then in each function in the servlet I made sure to set the characterEncoding on the request before it was ever used and on the response right before it was redirected or written to. That fixed the issue for me. No more question marks and no need to make lots of convoluted changes.

For future reference one team memeber suggested I try the character encoding CP1252, which made progress but didn't fix everything. Also there is a chance I didn't try it on every page before finding a page in the process I forgot about.

Another team member suggested I do the following:
new String(theTextToConvert.getBytes("Windows-1252"), "ISO-8859-1")
That also seemed to make progress but still didn't work fully and I would have had to make about 500 changes in several files instead of just 10 in two files.