Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Difficulties updating JSF from 1.2 to 2.x and Richfaces from 3.3.2.SR1 to 4.3.7.Final  RSS feed

 
Steve Noack
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've been programming COBOL, z/OS Assembler and REXX for years, but am still fairly green at Java. I had a hand in developing a couple internal web apps in our shop. They run on JBoss AS 7.1.1.Final. They are currently using JSF 1.2 and facelets and Richfaces 3.3.2. I have now been tasked with upgrading them to JSF 2.x. From what I have read, Richfaces 3.x doesn't play the greatest with JSF 2.x, so I should upgrade Richfaces to 4.x, too. I now have an .ear file that will deploy, but there are (at least) two problems at this point. First, none of the GUI features show. All of the text shows up, but none of the background colors or boxes around the text appear. My second issue is that although (some form of) the login page displays, when I click the action button that is supposed to start the authentication and direct the user into the application, I get no error messages in the JBoss log, but what gets returned to the browser is what appears to be some Java code (not mine) and the url in the browser address field is (local host address)/javax.faces.resource/richfaces-event.js.faces.

I have removed facelets and JSF from WEB_INF\lib (using the version of JSF included in JBoss AS 7.1.1), replaced the Richfaces 3.3.2 jars with Richfaces 4.3.7 jars, and I was forced to change some of the code to account for dropped/changed methods and properties between Richfaces 3.x and 4.x. However, I don't believe any of those changes were in the login page.

Any suggestions as to where to look for what may be wrong?
 
Tim Holloway
Bartender
Posts: 18531
61
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the JavaRanch, Steve!

Editorial comment: If your app contains login code the technical term for it is "hacked". I always recommend using the J2EE standard security system unless you've either got really strange security needs - and I mean REALLY strange - or you're a full-time Java security expert with no silly distractions like getting applications done. Being "clever" is not sufficient when it comes to security. Assuming you're using the standard security system already, your problem would sound like you're attempting to use JSF on the login page. More on this in a moment.

OK. On to the Main Event. JBoss/WildFly from roughly version 6 on is JEE compliant, not J2EE. In JEE, JSF is part of the core spec and as a result, JSF is built into the webapp server (JBoss) itself. You would not normally include the core JSF class libraries in the WAR/EAR. People migrating apps from Tomcat servers learn this the hard way. If you do include your own JSF core libs. then you'll need some special directives in web.xml to tell JBoss about it or there will be serious conflicts. See the JBoss docs for details.

The last time I saw something comparable to the RichFaces 3-to-4 upgrade debacle it was when Microsoft moved from VB to VB.NET. They didn't appear to make any effort at backwards compatibility. They apparently hoped you'd pay their consultants to do a long and tedious job. As a result, almost all of my apps are stuck on RF3 to this day and I'm having to stuff in extra headers to make IE9, 10, and 11 run under it (they are now and forever limited to IE8).

I am not amused, in other words. Seriously. Not Amused. I keep considering moving to something like PrimeFaces, because it's going to cost about the same either way.

RF3 can run with JSF2, but with reduced compatibility. None of the new tags will work, including f:ajax Like I said, no apparent attempt to provide a migration path.

The "java code" you're seeing returned may actually be JavaScript. That's what should be returned by that URL. But unless you ask for that URL specifically, it shouldn't normally display. On the other hand, if you're using JEE standard container security and your login page is in JSF, that can be a problem. Login pages and other pages defined in web.xml are not invoked directly from the normal URL processing mechanism, they're invoked directly from the server itself. Depending on the brand and version of the server, that can be a major problem, since the internal invocation mechanism may not invoke the FacesServlet. JSF isn't the only platform that has issues on that score.

For security reasons AND compatibility reasons, I recommend a stark login page with no fancy decorations, no menus or other callouts, nothing that isn't directly related to being a login form. A plain HTML or JSP page for preference.

Finally, just because so many people get confused by this: An attempt to submit a login page directly via URL request won't work. "j_security_check" is not a URL, it's a marker to tell the container to continue a login in process. Only the container can initiate the login process, which it will do on the first attempt to process a protected URL. You can't just call the login form yourself.
 
Steve Noack
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you, Tim, for the pointers. It gave me ideas of where to look for the cause/solution.

We are using Spring and authenticating against our mainframe security server (when testing on a local instance, the actual authentication call is bypassed and an 'authorized' result is returned. We are utilizing Spring context .xml to enforce authentication and the users are not specifying the login page, but are being redirected appropriately. There are no options on the login page other than log in. I have gotten the Richfaces 4.x skinning to work, for the most part. It doesn't show for the inital login page, but if the user returns to the login page - even after closing the browser and restarting it, the page looks uniform with the rest of the app - like I expect. If the login page is not skinned properly, that is not a show stopper. I can live with that.

My problem now must have to do with initialization of some sort. The first time the app is invoked by a browser after starting the JBOSS web server or redeploying the app, I get the login screen (unskinned), I enter a valid userid/password and what gets returned is either that same javascript (and I agree that it is most likely javascript and not java) or another listing of a different set of javascript code. If I hit the browser's back button and enter userid/password again (same combination or different - doesnt' matter), the desired page loads properly. I get the same results on both Chrome and IE (first call fails, second works) for the same deployment on the server. The first call for each browser fails and the second works - even if I already did it on the other browser for this deployment. It doesn't seem to matter if I cycle the browser. Once I have gotten the page to load, I can cycle the server, invoke the app again (getting redirected to the login page - which displays with the desired Richfaces skinning) and get into the app with no issues. But cycle the JBOSS server and reload the page and it the login page will be unskinnned and the app page will fail to load until I go back and re-log in.

Suggestions as to what I might still be missing? Like I said, I can live with the login page not being as 'pretty' as I want, but I can't release it to the masses and say 'Oh, the first try will crap out, just hit your back button and do it again.' Getting a 'pretty' login page would be a bonus at this point. :-)

 
Tim Holloway
Bartender
Posts: 18531
61
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
OK. Just some general info.

Spring provides a security framework, but it works best in conjunction with J2EE standard security. That way you can use the container for coarse-grained security (login and general authorizations) and let Spring handle fine-grained security. A number of famous J2EE products do this. I think that Pentaho was doing that at one time and that Sonatype Nexus is doing that now.

To leverage container security with a security authentication (mainframe-based or otherwise), you'd need an appropriate Realm. For example, for Tomcat, a Realm module could be written to invoke RACF client services. For WebSphere, hopefully IBM's already got something intergrated. Last WAS server I dealt with was attached to an iSeries, and it was being troublesome, so I didn't spend much time on the security subsystem.

I've done this kind of stuff. One place I worked set up a web service on a Solaris server and I wrote a Realm that employed it.

One advantage with Realm-based security is that you can test a secured webapp without making code changes. Simply setup a MemoryRealm and instead of querying the mainframe, testers can set up security in the tomcat-users.xml file, for example. Realms are completely plug-replaceable.

I'm perhaps misunderstanding some other problem, but one "downside" to J2EE container security can be found in the API. There's no "login" listener defined. You cannot (officially) tell when someone has logged in. There are some good reasons for that, including the fact that if you're operating in a single-signon environment, you don't log into an app, you log into the environment, so you may enter the app already logged in, or not.

Another reason is that you can create secured bookmark URLs. Using the container security system, if I have a favorite place, I can bookmark it, and if I'm not logged in, the login screen gets presented and processed and then control goes directly to the bookmarked page. I generally think it rude to have my request hijacked and get pushed to a "home" page just because I wasn't previously logged in.

However, there are times when that's what's wanted. You don't get a notification when someone logs in, but you can setup a servlet listener. If the HttpURLRequest returns "null" from the getRemoteUser() method (or from getUserPrincipal()), then the user is not authenticated. If it returns non-null, then the user has been logged in somewhere, sometime and is still logged in. If a request comes in with a valid remote user, but the previous request had not, you'll see the transition from null to not-null in the servletListener (assuming you cached the user state/id in a session object), and that will allow you to redirect the original login request and push the user towards your chosen post-login process.

That information may or may not help in designing around your particular problem.

As far as the problem itself goes, I'm not sure. One thing that's a good idea when restarting a webapp server is to delete the temp and work directory contents. Otherwise stale leftovers from previous sessions may get pulled in and cause unpredictable behavior. This is an especial problem if the WAR has had changes made that make the old session data no longer applicable.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!