Asked  7 Months ago    Answers:  5   Viewed   24 times

Yesterday I saw a presentation on Java Server Faces 2.0 which looked truly impressive, even though I am currently a happy ASP.NET MVC / jQuery developer. What I liked most about JSF was the huge amount of AJAX-Enabled UI components which seem to make development much faster than with ASP.NET MVC, especially on AJAX-heavy sites. Integration testing looked very nice too.

Since the presentation only emphasized the advantages of JSF, I'd like to hear about the other side as well.

So my questions are:

  • What are the main disadvantages of Java Server Faces 2.0?
  • What might make a JSF developer consider using ASP.NET MVC instead of JSF?

 Answers

84

JSF 2.0 disadvantages? Honestly, apart from the relative steep learning curve when you don't have a solid background knowledge about basic Web Development (HTML/CSS/JS, server side versus client side, etc) and the basic Java Servlet API (request/response/session, forwarding/redirecting, etc), no serious disadvantages comes to mind. JSF in its current release still needs to get rid of the negative image it gained during the early ages, during which there were several serious disadvantages.

JSF 1.0 (March 2004)

This was the initial release. It was cluttered with bugs in both the core and performance areas you don't want to know about. Your webapplication didn't always work as you'd intuitively expect. You as developer would run hard away crying.

JSF 1.1 (May 2004)

This was the bugfix release. The performance was still not much improved. There was also one major disadvantage: you can't inline HTML in the JSF page flawlessly. All plain vanilla HTML get rendered before the JSF component tree. You need to wrap all plain vanilla in <f:verbatim> tags so that they get included in the JSF component tree. Although this was as per the specification, this has received a lot of criticism. See also a.o. JSF/Facelets: why is it not a good idea to mix JSF/Facelets with HTML tags?

JSF 1.2 (May 2006)

This was the first release of the new JSF development team lead by Ryan Lubke. The new team did a lot of great work. There were also changes in the spec. The major change was the improvement of the view handling. This not only fully detached JSF from JSP, so one could use a different view technology than JSP, but it also allowed developers to inline plain vanilla HTML in the JSF page without hassling with <f:verbatim> tags. Another major focus of the new team was improving the performance. During the lifetime of the Sun JSF Reference Implementation 1.2 (which was codenamed Mojarra since build 1.2_08, around 2008), practically every build got shipped with (major) performance improvements next to the usual (minor) bugfixes.

The only serious disadvantage of JSF 1.x (including 1.2) is the lack of a scope in between the request and session scope, the so-called conversation scope. This forced developers to hassle with hidden input elements, unnecessary DB queries and/or abusing the session scope whenever one want to retain the initial model data in the subsequent request in order to successfully process validations, conversions, model changes and action invocations in the more complex webapplications. The pain could be softened by adopting a 3rd party library which retains the necessary data in the subsequent request like MyFaces Tomahawk <t:saveState> component, JBoss Seam conversation scope and MyFaces Orchestra conversation framework.

Another disadvantage for HTML/CSS purists is that JSF uses the colon : as ID separator character to ensure uniqueness of the HTML element id in the generated HTML output, especially when a component is reused more than once in the view (templating, iterating components, etc). Because this is an illegal character in CSS identifiers, you would need to use the to escape the colon in CSS selectors, resulting in ugly and odd-looking selectors like #formId:fieldId {} or even #formId3A fieldId {}. See also How to use JSF generated HTML element ID with colon ":" in CSS selectors? However, if you're not a purist, read also By default, JSF generates unusable ids, which are incompatible with css part of web standards.

Also, JSF 1.x didn't ship with Ajax facilities out of the box. Not really a technical disadvantage, but due to the Web 2.0 hype during that period, it became a functional disadvantage. Exadel was early to introduce Ajax4jsf, which was thoroughly developed during the years and became the core part of JBoss RichFaces component library. Another component libraries were shipped with builtin Ajax powers as well, the well known one being ICEfaces.

About halfway the JSF 1.2 lifetime, a new XML based view technology was introduced: Facelets. This offered enormous advantages above JSP, especially in the area of templating.

JSF 2.0 (June 2009)

This was the second major release, with Ajax as buzzword. There were a lot of technical and functional changes. JSP is replaced by Facelets as the default view technology and Facelets was expanded with capabilities to create custom components using pure XML (the so-called composite components). See also Why Facelets is preferred over JSP as the view definition language from JSF2.0 onwards?

Ajax powers were introduced in flavor of the <f:ajax> component which has much similarities with Ajax4jsf. Annotations and convention-over-configuration enhancements were introduced to kill the verbose faces-config.xml file as much as possible. Also, the default naming container ID separator character : became configurable, so HTML/CSS purists could breathe relieved. All you need to do is to define it as init-param in web.xml with the name javax.faces.SEPARATOR_CHAR and ensuring that you aren't using the character yourself anywhere in client ID's, such as -.

Last but not least, a new scope was introduced, the view scope. It eliminated another major JSF 1.x disadvantage as described before. You just declare the bean @ViewScoped to enable the conversation scope without hassling all ways to retain the data in subsequent (conversational) requests. A @ViewScoped bean will live as long as you're subsequently submitting and navigating to the same view (independently of the opened browser tab/window!), either synchronously or asynchronously (Ajax). See also Difference between View and Request scope in managed beans and How to choose the right bean scope?

Although practically all disadvantages of JSF 1.x were eliminated, there are JSF 2.0 specific bugs which might become a showstopper. The @ViewScoped fails in tag handlers due to a chicken-egg issue in partial state saving. This is fixed in JSF 2.2 and backported in Mojarra 2.1.18. Also passing custom attributes like the HTML5 data-xxx is not supported. This is fixed in JSF 2.2 by new passthrough elements/attributes feature. Further the JSF implementation Mojarra has its own set of issues. Relatively a lot of them are related to the sometimes unintuitive behaviour of <ui:repeat>, the new partial state saving implementation and the poorly implemented flash scope. Most of them are fixed in a Mojarra 2.2.x version.

Around the JSF 2.0 time, PrimeFaces was introduced, based on jQuery and jQuery UI. It became the most popular JSF component library.

JSF 2.2 (May 2013)

With the introduction of JSF 2.2, HTML5 was used as buzzword even though this was technically just supported in all older JSF versions. See also JavaServer Faces 2.2 and HTML5 support, why is XHTML still being used. Most important new JSF 2.2 feature is the support for custom component attributes, hereby opening a world of possibilities, such as custom tableless radio button groups.

Apart from implementation specific bugs and some "annoying little things" such as inability to inject an EJB in a validator/converter (already fixed in JSF 2.3), there are not really major disadvantages in the JSF 2.2 specification.

Component based MVC vs Request based MVC

Some may opt that the major disadvantage of JSF is that it allows very little fine-grained control over the generated HTML/CSS/JS. That's not JSF's own, that's just because it's a component based MVC framework, not a request (action) based MVC framework. If a high degree of controlling the HTML/CSS/JS is your major requirement when considering a MVC framework, then you should already not be looking at a component based MVC framework, but at a request based MVC framework like Spring MVC. You only need to take into account that you'll have to write all that HTML/CSS/JS boilerplate yourself. See also Difference between Request MVC and Component MVC.

See also:

  • What is the difference between JSF, Servlet and JSP? (just to understand the basics)
  • Using JSF to develop tableless CSS layouts (another myth about JSF)
  • JSF vs plain HTML/CSS/JS/jQuery (when JSF is the wrong choice)
  • Design patterns in web applications (illustrates the ideology behind MVC)
Tuesday, June 1, 2021
 
Zigglzworth
answered 7 Months ago
18

why dont you check if there is a returnUrl before your custom redirects?

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {
         if (ModelState.IsValid)
         {
              var user = await UserManager.FindAsync(model.UserName, model.Password);
              if (user != null)
              {
                    await SignInAsync(user, model.RememberMe);
                    if (String.IsNullOrEmpty(returnUrl))
                    {
                         if (UserManager.IsInRole(user.Id, "Employer"))
                         {
                             return RedirectToAction("Index", "Employer");
                         }
                         //role Admin go to Admin page
                         if (UserManager.IsInRole(user.Id, "Admin"))
                         {
                             return RedirectToAction("Index", "Admin");
                         }
                     }
                     else
                     {
                         return RedirectToLocal(returnUrl);
                     }
              }
              else
              {
                     ModelState.AddModelError("", "Invalid username or password.");
              }
       }

       // If we got this far, something failed, redisplay form
       return View(model);
   }

Like this if you navigate to foo.com/admin it will throw 401 and redirect you to login. Then if you log in as employer it will throw 401 and redirect you back to login again.

From comments: "Can I just do Redirect(returnUrl) and delete the RedirectToLocal action method?"

RedirectToLocal(returnUrl) method checks if Url.IsLocalUrl(returnUrl). So it is needed to prevent Open Redirect Attacks.

Thursday, July 29, 2021
 
saad
answered 5 Months ago
53

Okay. I started on a new project that incorporates the best from S#arp Architecture with stuff, that work on mono. Instead of T4Toolkit it uses a ruby script to do the generation job, just as with rails or merb.

To use install the shaml gem from github:

gem install shaml

Then create a new application:

shaml generate app AppName

And create resources:

shaml generate resource NewRes "name:string;date:DateTime"

S#aml Architecture project homepage: http://shaml.sztupy.hu/

GitHub project: http://github.com/sztupy/shaml/tree/master

Sunday, August 8, 2021
 
tika
answered 4 Months ago
96

You can create two-way anonymous pipes using CreatePipe() Win32 API call, so piping input/output is not the only way. You simply get a new file handle you can give to the other process.

Anonymous pipes are based on shared memory, but do not support asynchronous operations (through ReadFileEx, ReadFileWrite). Performance issues (disadvantages) are thus 1) synchronous operation, 2) memory copying, 3) interprocess synchronization. Generally, "raw" shared memory (memory mapped file without an actual backing file) and named pipes will be faster, and sockets and Window messages will be slower (than anonymous pipes).

You cannot use I/O Completion Ports (IOCP) with anonymous pipes, instead you'll have to "poll" the pipe, incurring extra context switches. In addition to serializing the data, the serialized data has to be copied around in memory, as you cannot write directly to the shared memory. One process also has to wait for another, implying that the other process has to signal an interprocess synchronization primitive. Performance depends heavily on the size of the messages (ratio of read/write calls to amount of data sent), because for each read/write the process has to make context switches and possibly spin/sleep.

All methods except "raw" shared memory require memory copying and some sort of interprocess signaling (synchronization), so the main disadvantage of anonymous pipes is synchronous operation. You'll hit the ceiling when transmitting large number of messages, when the CPU spends most of its time doing context switches.

Performance-wise, named pipes are better because you can have worker thread(s) processing async notifications using IOCP, and can even receive multiple messages with one call, thus reducing the API overhead. If making your own components, the extra trouble from giving a name to the pipe is well worth the trouble (and you can even connect across networks). Later Windows versions implement special routing for local sockets, which also do support IOCP.

The fastest method would be to use shared memory directly, but then you will have to take care of interprocess synchronization yourself. It's possible to implement lock-free pipes yourself, but in case you're not constantly transmitting data, you'll still have to use synchronization primitives to notify/wake the listening process up.

Also note that using files does not imply that you would be limited by disk speed, as you can use memory mapped files and even with normal files, the cache manager handles the reading/writing. The other methods (RPC, clipboard, etc) are based on these "standard" methods, which means they'll just add some extra layer of protocol and are meant to be easier/more helpful, or more suitable for some programming environment (but not to be faster).

Thursday, September 16, 2021
 
ranhan
answered 3 Months ago
80

You'll really have to performance test - There is no Yes/No answer. As per Andy Living's post above links to, a CTE is just shorthand for a query or subquery.

If you are calling it twice or more in the same function, you might get better performance if you fill a table variable and then join to/select from that. However, as table variables take up space somewhere, and don't have indexes/statistics (With the exception of any declared primary key on the table variable) there's no way of saying which will be faster.

They both have costs and savings, and which is the best way depends on the data they pull in and what they do with it. I've been in your situation, and after testing for speed under various conditions - Some functions used CTEs, and others used table variables.

Sunday, November 21, 2021
 
ryeballar
answered 3 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share