• SG (unregistered)

    One small detail - the exception handling writes the message to stdout, and the stacktrace (including message) to stderr. so the double-logging isn't quite as stupid as it looks, since it's potentially logging a short message to one place and a much more verbose error to another.

    The code is still crap, of course, but that particular bit may have some loose rational behind it, if stdout and stderr were going to different places.

  • Nick Diamond (unregistered)

    Also, if the second call fails (for two times in a row), then return an empty string instead of null. Because, why be consistent?

  • WTFGuy (unregistered)

    IANA Java dev so this may be bogus thinking ...

    As I see it, in addition to returning a result, or "", or null the thing can also throw out whatever exceptions other than PortalException or SystemException the underlying utility functions throw.

    As a longtime SharePoint dev starting with v1.0 (don't ask) by far the hardest part of dealing with the ginourmous and ever-growing API was the vast array of undocumented corner cases and emergent exceptions.

    Through hard won experience you eventually learned "all" the ways any given API call to get even a simple string property could bite back. And developed a set of wrappers to regularize / predictable-ize that behavior so you weren't copypasta-ing all the guardrail code to everywhere it was needed.

    Which of course meant now you'd built your own partial wrapper for their giant wrapper. Which was then sort-of invalidated when SharePoint vNext came out. Since none of the aberrant behavior was contractual, maybe they "fixed" it different and maybe they didn't. Or maybe it grew a new batch of corner cases you'd only discover when they started happening at the customers' sites'.

    Near-infinite configurability makes integration testing into a project of an O(n^m) scale. On an O(1) budget.

    It's morning here as I type this but I suddenly feel my PTSDD* acting up so I may need a drink soon**.

    *: Post-Traumatic SharePoint Developer Disorder **: Just kidding; no self-harm here.

  • (nodebb) in reply to WTFGuy

    I'm pretty sure the whole idea behind Sharepoint was to bilk a whole bunch of companies out of a lot of cash, using "collaboration" and "social networking" as buzzwords to convince silly managers to sign on the dotted line. "A fool and his money will be separated."

  • (nodebb) in reply to WTFGuy

    As I see it, in addition to returning a result, or "", or null the thing can also throw out whatever exceptions other than PortalException or SystemException the underlying utility functions throw.

    This is Java, which (if memory serves - IANAJP) has binding compile-time exception declarations. If a function doesn't declare that it can throw X type of exception (with a couple of slightly obscure allowances), it must catch X, or the compiler will give it the big one-fingered salute. This one doesn't declare any, therefore the methods it calls don't throw anything except what's caught explicitly.

  • Scott (unregistered) in reply to Mr. TA

    "A fool and his money are lucky enough to get together in the first place" --Gordon Gekko

    Isn't that true of most enterprisy things though? BizTalk was a disaster. I understand the big software packages (blanking on examples right now) to really be, "sign with us for cheap, but nobody can develop against our APIs, so we'll make a ton of money in consulting fees."

  • Naomi (unregistered) in reply to WTFGuy

    Ish.

    At a language level, Java distinguishes between checked and runtime exceptions (and errors). Anything can throw a runtime exception or an error, but if a method throws a checked exception, it has to declare that it throws it - and it's transitive, so if a() calls b() and b() declares a checked exception, a() has to declare the same (or a more general) checked exception.

    In theory, checked exceptions are potentially recoverable - FileNotFoundException is checked because you might be able to recover from it (in an interactive application, you might just need to ask the user to check that they spelled the filename right). On the other hand, runtime exceptions aren't recoverable - a NullPointerException or an IllegalArgumentException or what have you represents an actual bug, so there isn't much you can do about it at runtime (although the language will still let you catch them if you want to). And just for completeness's sake, errors represent low-level problems like overflowing the call stack, and they work a lot like runtime exceptions but aren't technically exceptions to make it harder to catch them by accident.

    Since this method doesn't declare any checked exceptions, it's the only exceptions that can bubble up from the underlying utility functions are runtime exceptions and errors - bugs and system-level problems. As long as the underlying utility functions adhere to the convention, you shouldn't be safe from unexpected exceptions - but for better or for worse, you're trusting that they do.

  • hj (unregistered)

    I spent 7 years doing WebSphere Portal development and none of this is surprising to me. WebSphere Portal is quite bluntly the most awful, unreliable piece of software ever developed. The pattern of "try to get this thing from WebSphere Portal and if that fails try to get it again using a different method" is very common in all WebSphere Portal code I've seen because API calls will randomly fail for no discernible reason. The duplicate error logging is a sign of desperation because you never know whether the out & error streams will work. I joked many times that WebSphere Portal startups are like snowflakes, no two are ever the same. Sometimes it will just not set the system out or error stream or start writing them to a new location. On the next restart it will be fine. This may not be great code but it's exactly the type of "desperation based design" that's required with WebSphere Portal.

  • Truism (unregistered)

    It's been said that the sign of madness is trying the same thing and expecting different results. It seems this developer decided to "Yo Dawg" the madness.

  • (nodebb) in reply to Nick Diamond

    Also, if the second call fails (for two times in a row), then return an empty string instead of null. Because, why be consistent?

    Well duh! How else are you going to tell how many times it tried!

  • P. Wolff (unregistered) in reply to Nick Diamond

    Empty string instead of null?

    According to Oracle, they're absolutely identical. And because it's Oracle who says so it is the only Enterprise(tm) way to look at it.

  • P. Wolff (unregistered) in reply to P. Wolff

    The Oracle database, that is.

    Maybe they've enough to do with [del]messing up[/del][ins]improving[/ins] Java they didn't find an opportunity to allow Java to see that ""==null yet.

  • ooOOooGa (unregistered)

    Well, if PortalUtil.getLayoutFriendlyURL throws an exception, then running it again is indeed silly. But if instead it is LayoutLocalServiceUtil.getFriendlyURLLayout that is throwing the exception, then running PortalUtil.getLayoutFriendlyURL ... would be better to be run after the try/catch for LayoutLocalServiceUtil.getFriendlyURLLayout - assuming that it can do its job with null passed in for its first argument.

    OK. Enough for trying to defend the WTF code.

  • sizer99 (google)

    getLayoutFriendlyURL probably isn't one of them, but... I've certainly run into stuff in Java's bloated putrescent legacy libraries that will probably work this time if you call them again with the exact same inputs. Like a 99% chance of success, 1% of randomly exploding, so if you call it twice there's a 99.99% chance of success. Of course then you could put a while() around it, but sometimes it IS a legitimate error, so that would be infinite loop. Basically there's no solid way to deal with it other than not using it.

  • (nodebb)

    Looks like if the first attempt gets a null back, then it tries the same function but with different inputs, something like "if you can't load the desired theme then try loading the generic theme instead". Still could be clearer about what it's doing and why, but the high-level concept seems to make sense, at least.

  • Toad (unregistered)

    "the route of containers and service-providing classes and runtime bindings and dynamic hooks and lookups well before anyone else" other than VB.

  • (nodebb)

    Everybody needs to look more carefully at the code.

    The only way the second attempt can be tried is if the first

    selectedLayout = LayoutLocalServiceUtil.getFriendlyURLLayout(theme.getLayout().getGroupId(), false, friendlyURL);
    

    returns non-NULL without throwing and then the

    return PortalUtil.getLayoutFriendlyURL(selectedLayout, theme);
    

    throws.

    In that case, it really is a call with the same parameters, and it will throw again (unless it has a non-deterministic throw-y bug), meaning the return values are the layout-friendly URL or NULL, with no possibility of an empty string.

    Leaving the non-deterministic throw-y bug in place is TRWTF.

  • (nodebb) in reply to sizer99

    I've certainly run into stuff in Java's bloated putrescent legacy libraries that will probably work this time if you call them again with the exact same inputs.

    This is an ongoing problem for me when making webservice calls to certain SaaS applications hosted by the big O. The call fails for no discernible reason and the fix is to clean up and try again. I deal with this on literally a nightly basis.

  • owlstead (unregistered)

    First thing to do in any Java IDE: replace the printing of the e.printStackTrace() with:

    // TODO think of better exception
    throw new IllegalStateException("Unhandled exception", e);
    

    Then you don't even have to assign bogus null or empty strings to the local variables: you either throw a runtime exception (with full stacktrace) or your assignment has worked.

  • doubtingposter (unregistered)

    e.printStackTrace() prints the stacktrace to system.err, not system.out. And those two streams don't have to be pointing to the same display / log. With webservers it's common that they aren't.

    Of course, you should be using a propper logging solution, though Remy has already shown in the past he doesn't know how those work either.

Leave a comment on “To Repeat Yourself”

Log In or post as a guest

Replying to comment #:

« Return to Article