Wednesday, June 19, 2013

The importance of servlet-mapping

Ok, let's go ahead and set the stage here.  I've been trying to configure Spring and Jersey to play well together in Tomcat.  Specifically, I'm trying to use the latest and greatest of my dependencies - so, for now that means Spring 3.2.3-RELEASE, and Jersey 1.17.1, with Tomcat 7.0.21.

Now, I have everything configured correctly for Spring - I see that the beans are being created by the DefaultListableBeanFactory line in my Tomcat console.  Everything should be good.  I have double checked my web.xml, and I have the correct contextConfigLocation and ContextLoadListener in my it.  I've also changed my servlet to use com.sun.jersey.spi.spring.container.servlet.SpringServlet, which should allow Jersey to see all of my Spring beans. 

But, I still am getting the dreaded Null Pointer Exception, letting me know that my Jersey services sure aren't getting injected.  I've tried everything - changing annotations from @Component to @Service.  Setting the name of the @Component.  Creating unnecessary Interfaces.  Sleeping on it to make things magically make sense.  Nothing!

Then, I notice one thing - I have a servlet-mapping (which hasn't really seemed to do much to this point for some reason) that's url-pattern is /ws.  Well, I went ahead and changed that to end in /*, which allows it to do pattern matching instead of exact matching.  *Poof*!  Everything suddenly works.

Hope that helps someone else that runs into this issue.

Wednesday, January 4, 2012

"Value does not fall within the expected range." When Adding a Control in Code

"Value does not fall within the expected range" is an error I expect to receive when attempting to access an element of an Array that does not exist.  Unfortunately, I have spent the last day receiving this message intermittently when trying to perform an Add on a UIElement's Children in Silverlight.

If you're like me, you received this error and immediately started Googling how to fix it by typing in the error and adding things like "Add" and "Silverlight."  If you do this, you'll find a few results - almost exclusively about namescope conflicts.  Well, there's a reason - that really is the problem no matter what all of your other investigations point towards.

Here were my exact symptoms: I was adding a context menu to a Grid dynamically.  When the Grid initially loaded, the context menu was added.  It was performed this way so that we could have a generic GridBehavior that included the ContextMenu instead of having a hard coded ContextMenu on each of our Grids.  However, this code worked fine for years - why did it suddenly break?

Well, what changed?  We had recently performed a merge, and this is when the problem started occurring.  So, easy enough - I rolled back all of the GridBehavior changes (this is where the error was actually occurring after all), as well as any other file that seemed to be impacted by the GridBehavior changes (those that didn't build correctly after I rolled the first file back).  This would fix it if it were merge related right?  Well, no luck - it still failed.

What else can I try?  Well, everything told me that it was about namescope conflicts.  So, right before I added the control, I appended a random modifier to the Name - this should fix it, right?  No luck.

What if I check for the Name to be used in the namescope of the parent I was adding it to?  Or even the Application's RootVisual?  Well - I told you that this error was occurring intermittently, and none of these checks coincided with whether the error would occur or not - they would always be either true or false, but not change based on whether the code blew up.

Then I noticed something - this control had a name.  And it received that name in the XAML.  I started thinking about this for a bit, and I wondered how long it had had that name.  Checking the history - it received it in that last merge!  Therefore, I ripped that name out and started testing again.  Lo and behold, everything worked!

Here's the moral of this story: that error message really is about a namescope conflict.  Believe it!  It's somewhere in there!  Secondly - don't name things in XAML that don't need names - especially don't do this if you're later going to add them dynamically - you can't guarantee that you'll only add it once instead of multiple times in the namescope!

Friday, December 30, 2011

Silverlight Screen Disabling When Closing ChildWindow

An obnoxious problem has been plaguing a project that I've been working on for the last couple of months. As we would be testing various pieces of functionality, the screen would inexplicably become completely disabled. Now, we were working in a TabbedPane, so it was quite odd that the entire browser screen was being disabled (and not just our current Tab). Well, as I'm sure you realize - this is not acceptable production behavior! So, as we began drawing closer to our release date, this became more of a pressing concern - and so I was able to dedicate several hours to investigating the problem (and now writing this so that I didn't forget the solution!)

Ok, here are the steps I found to reproduce.
  1. Go to a certain tab
  2. Bring up the ChildWindow
  3. Click the "X" (built in Close) button
  4. Go to a different tab
  5. Bring up a different ChildWindow
  6. Close the new ChildWindow
  7. *poof* your screen was disabled!

So, if you're like me, you assume that the problem is in the second ChildWindow - after all, that's the one showing the symptoms... except that it works most of them time - just not when you go to the other ChildWindow first.

Anyway, I scoured the Internet looking for anyone that was having any kind of similar problems. There were people talking about setting both a DialogResult and calling the Close() method, so I looked for that. Nothing.

There were people that talked about calling Close() twice (setting DialogResult actually calls Close() so this is really the same as the last problem). I looked all over the ChildWindow that was exhibiting the symptoms - still nothing.

What actually happened was that my FIRST ChildWindow was calling Close() from the Closing event handler, because it was calling an inherited block of code without realizing all of the implications - and this somehow decided to mess up the next ChildWindow's close operation. Who knew?

So, long story short - if you're experiencing a disabling of your main screen when a ChildWindow closes, look for Close() to be called twice - but be mindful of Close() being called on a previous ChildWindow after it is already in the Closing event handler as well!

Wednesday, November 2, 2011

Validation States on TextBox in Silverlight

So, one of the requirements on the project that I'm working on is that we have a Silverlight TextBox that has to display the error balloon/tooltip. Simple, right? However, this TextBox is actually just displaying data, and the data is entered through a dialog, not directly as text on the screen. Furthermore, to ensure that the user does not attempt to enter the data directly, the TextBox is disabled.

You may know where I'm going with this - my Validation Error tooltip never appears! Why? The default style of a TextBox only shows the tooltip in a focused state! Eventually, I realized this. After looking in the MSDN documentation about TextBox, I was able to get the default style of a TextBox, and I was able to override it's InvalidUnfocused state to do the same as the InvalidFocused state - and it worked!

Now to find a more intuitive way for the user to see that error message without it always being on the screen...

Sunday, September 25, 2011

Why is my Silverlight DataForm acting like that?

The other day, as I was using Silverlight, I put a DataGrid inside of a DataForm. Seems innocent enough, right? Specifically, what I wanted to accomplish was to allow users to add elements to a DataGrid with drag and drop functionality. Therefore, there were two DataGrids - one that the user dragged from, and the other that would receive the drop event. What I noticed, though, was that the added elements were not being saved.

We are using WCF RIA services, so I first assumed that I had created my composition objects incorrectly, and so I spent quite a bit of time looking into and verifying that code. After adding more and more breakpoints, I discovered that the WCF RIA service call was not to blame - the added elements were not even in the Submit operation, and so they were being removed sometime before the Submit was called.

Next, life got even more strange - if I edited one of the DataFields on the DataGrid, and then I dragged an item over, everything saved correctly. This left me quite puzzled. Then, eventually, a co-worker helped me discover the problem (which I thought was strange enough to warrant a blog post - maybe this will help other people (or even myself) next time one of us runs into this situation).

A Silverlight DataForm Rejects changes on EditEnded.

What? Yeah, I thought that this was quite strange. Why was I hitting this event? My "Save" button was not in the DataGrid! However, once you know this, it is easy enough to fix. Handle the EditEnding event on the DataForm and mark the event canceled:

private void DataForm_EditEnding(object sender, DataFormEditEndingEventArgs e)
       e.Cancel = true;

Done! Now my DataForm stopped rejecting my changes.

Tuesday, July 5, 2011

Making Values Required in a Silverlight DataForm

For those of you who have done validation in a Silverlight DataForm before, you probably are used to setting the [Required] attribute above all of the necessary fields in your WCF RIA project. From there, .NET will auto-magic the necessary code and, combined with lots of NotifyOnValidationError and ValidatesOnExceptions tags (and potentially some GetBindingExpression().UpdateSource()), viola! it will successfully perform validations. However, I ran into a situation where I was actually taking a couple of fields and transforming them into a single field from my WCF RIA service data object. After a long time of scratching my head, I was really stuck on trying to figure out how to force this validation to work. I had tried setting the [Required] attribute on the field they were bound to, added all the usual NotifyOnValidationError tags... nothing.

Eventually, I realized how to get around this issue (and it made me feel a bit silly for not coming up with this earlier.) You know where we set "ValidatesOnExceptions=true"... well... let's throw a ValidationException! So, in the setter of the property that I was binding the DataField to, if the data was invalid, I simply threw a ValidationException. Poof! It suddenly started working. Is there a better way to do this? Probably. However, this was able to get me back on the right path, and I was able to resume being productive.

Friday, April 1, 2011

Systematically Update Binding in Silverlight

So, after quite a bit of time in Silverlight, I have learned that DataForms are very powerful entities.  However, they like to hide from me what they are doing.  Therefore, when I get into a situation in which I need to simulate their behavior, this often ends with me banging my head against a wall and typing my query into Google in as many different ways as possible.  Recently, I have been attempting to force a validation on an object that was not in a DataForm... and I had no idea how.  Fortunately, I stumbled upon this forum and it helped me.  So that you don't have to bother reading it (that's why you're at my site, anyway, isn't it?) I have placed the important code snippet here:

BindingExpression bindingExpression = myTextBox.GetBindingExpresion(TextBox.TextProperty);

Poof!  Your TextBox (assuming your TextBox variable is called "myTextBox") will validate.