• (nodebb)

    Boolean.class.getDeclaredField("true").set(Boolean.class, false);

  • dpm (unregistered)

    Oh my no. TRWTF is "production environment loaded slightly different Java classes". Overwriting private members takes a distant second to that.

  • Prime Mover (unregistered)

    That really is truly evil. It's a violation of privacy on a par with breaking into someone's bathroom and installing a camera under the seat.

  • Anonymous') OR 1=1; DROP TABLE wtf; -- (unregistered) in reply to dpm

    What dpm said. Your prod environment should differ as minimally as possible from your dev and test environments. Changing things like the database URL, sure, that's totally normal and good. Changing things like which classes get used by the entire runtime, that's no bueno.

  • RLB (unregistered)

    Not only all that, but it's a field called "singleton" that gets clobbered. That alone would make me shout at the perpetrator.

  • Steve (unregistered) in reply to Anonymous') OR 1=1; DROP TABLE wtf; --

    It's definitely one of those WTFs that make you suspect there's multiple other layers of WTFery just waiting to be, er, enjoyed ...

  • static (unregistered)

    Reflection is the only thing that makes using Java bearable.

  • Floutsch (unregistered)

    Huh, "YAGNIEIYTYD"... never heard of that. Neither has Google :D

  • MiserableOldGit (unregistered)

    That looks like the kind of scruffy hack created by some dinosaur fighting against the code/framework they have been "forced" to use. Although don't understand why it's only on prod configuration which, I agree, is a bigger offence.
    What I do think, is that if someone who'd do that sort of thing has been there any length of time you've got bigger, uglier crimes lurking in the codebase!

  • Naomi (unregistered)

    A safe rule of thumb when it comes to using Java's "reflection" features is that you definitely don't use them unless you absolutely need them, and if you think you need them, you're probably wrong. Or, to put it another way: YAGNIEIYTYD. You ain't gonna need it, especially if you think you do.

    I actually have to disagree with this, and there are really three reasons. The technically-correct-but-really-pedantic one is grabbing the name of a class for logging purposes - I think we can all agree there are cases where that's helpful, and it's really straightforward to do (X.class.getName() or x.getClass().getName(), depending on your use case). The less-pedantic-but-probably-irrelevant-to-most-people case is when you're writing a framework - a serialization framework looking at a class's members is kind of the point.

    The third case is when the reflection is controlled by annotations. Some class grabbing a random field of an unrelated class is a WTF. Some class grabbing a field that's annotated as "hey, other class, come grab this!" can be really useful, and as long as the API is clear, you'll know exactly what's going to happen and when. One of my (hobby) projects has an embedded scripting language (well, it's more like the project is a scripting language for a very specific purpose) and I've got an annotation to make a method written in Java part of the scripting language's standard library. It's so easy compared to having to manually register them, and the reflective code is all nicely encapsulated in one specific location.

    ...but that's obviously a pretty specific use case!

  • Jaloopa (partially registered) (unregistered) in reply to Floutsch

    Good job it's defined right there in the article then

    YAGNIEIYTYD. You ain't gonna need it, especially if you think you do.

  • Tim (unregistered)

    ASP.NET always had (still has for all I know) a "feature" that whenever you delete a directory underneath the web root, automatically restarts the application for you. This was not documented, not configurable, and doesn't happen in the development environment. I was able to use some nasty reflection code from stack overflow to disable the file watcher and it works fine in production to this day. Sometimes you just gotta do what you gotta do.

  • (nodebb) in reply to Tim

    The real problem is that your web application runs with enough privileges to modify itself. The better solution is to put the data somewhere separate from the application and make sure the application only has enough permission to its own code to execute it.

    Once this problem is solved, you'll find that ASP.Net's behavior is helpful as it picks up any changes to the application. It is important to handle state in such a way that it is maintained across application restarts, but the default behavior of resetting all session is preferable to blindly applying the existing session state to a new version of an application that wasn't designed with this in mind.

  • Wizofaus (unregistered) in reply to Anonymous') OR 1=1; DROP TABLE wtf; --

    And yet in principle a changed configuration value can have as much if not more impact on the correctness of your application's behavior as something like the example given. In fact my preference is to rely more on different build configurations than different runtime configuration values - the only time the latter is necessary is where the same software needs to run in different environments with different settings (or arguably if it's the sort of configuration that there's likely to be a need up change without having to rebuild and redeploy binaries, NYT these days that's usually trivial to do with a good CD system in place. )

  • Wizofaus (unregistered) in reply to Wizofaus

    Not sure how "but" got transformed into NYT! (Adjacent keys, sure, but still...)

  • Some Ed (unregistered) in reply to Jaloopa (partially registered)

    It's also probably worth mentioning that Google has heard about it. I mean, OK, it reports this article, as well as a tech news aggregator that is reporting on this site. But that's something, at least, right?

    But this is just the beginning. Soon it'll be everywhere. Or, at least, more places.

  • (nodebb) in reply to Tim

    "whenever you delete a directory" I thought it was whenever you change anything? IE update web.config... good idea for a class though lol

  • Some Ed (unregistered) in reply to Anonymous') OR 1=1; DROP TABLE wtf; --

    You say that, but I've seen compelling arguments for having debugging frameworks in non-prod that aren't there in prod. That is, of course, the opposite situation as what you see here. Also, the companies I've seen pull off that sort of configuration properly don't let something leave the non-prod environment if any of the automated testing is triggering any exceptions that debugging framework would be catching, despite the fact that one of the functional tests the stuff is subjected to is the random input/random controls test, which generates a recorded (so it can be replayed and analyzed if it actually catches anything) stream that is designed as much as feasible to work like a monkey that can see the controls and is really interested in messing with them... for hours.

    Another sort of package I've seen suggested for non-prod only is the test coverage testing software. So long as we don't have business rules which preclude taking the entirety of production code and placing it into a non-prod environment for re-evaluation purposes, there's little point in testing the unit test coverage in production.

    To be fair, in these non-prod environments, there's also a fair amount of testing done without those additional frameworks. They exist for the explicit purpose of enabling additional testing and/or gaining additional data from testing, not to provide a padded room for the protection of fragile applications.

    OK, I've seen arguments for not having unit tests in production, but that tends to allow you to do a relatively quick sanity test that things should be working there, so long as the unit tests can run without making changes to the production database. (You have database mocking as part of your unit tests, right?) Of course, most of the time when I've tested unit tests in production, it's more a test of the unit test's fitness than it is the code's fitness at that point. I mean, the usual trigger is we've found a behavior in prod that we thought was covered by a unit test.

  • (nodebb)

    The framework allows it and provides methods for doing it. It's not forbidden by any written or oral law or provision.

    There are much more abominable acts of immoral turpitude going on in any financial institution and stock exchange, not forbidden by law, and most people consider them as "market freedom".

    Whatever is not forbidden, it is allowed.

  • Nick (unregistered) in reply to Some Ed

    You run Unit Tests in a Production environment?

    I can’t even contemplate how that would work... In my (JVM-based) world, a Unit Test is something that’s run at build time, exists separately from the application code (i.e. separate classes and JAR files), and is launched externally, usually using some kind of test runner...

    In my world, even if I somehow deployed the Unit Tests to the Production server, and ran them on that server, it still wouldn’t actually be running the tests in Prod, since the online Production application would still be a separate process, unaffected by the fact I was running some other command on the same machine...

  • Best Of 2021 (unregistered)

    I've had to do similar kinds of hackery to this, when using a third party library that makes some assumptions about things that are no longer true, and bakes things into private variables, but all it takes to fix an issue is making it configurable. TRWTF here is not the reflective hackery - I'm sure the developer that did that had a good reason for using another cache manager, and presumably the framework doesn't let you configure it. TRWTF is that it isn't happening in dev or on staging so you didn't find out until it hit production that you'd broken that. And possibly that there's no comment explaining why it's necessary.

    Reflection's available in modern languages for good reasons, it just isn't correct to say you should never use it. Things like serialisers, ORMs and the like use it all over the place. So do configuration-on-demand/IoC frameworks like Spring. It's a tool that you can use to do a lot of damage if used wrongly, so one should be careful about when it's appropriate, but it can be very useful.

  • Tom Spander (unregistered)

    I work at a university and we use Reflection a lot. We give students coding assignments that need to pass automatic tests, and to ensure they have the correct modifiers and visibilities on their fields we check them with Reflection. So I guess that is one use case where the meta-level comes in handy.

  • linepro (unregistered)

    Had to do this once on prod code to install a security proxy because the core infrastructure team wouldn't use injection or provide a setter no matter how much we pleaded. Once 70% of the teams were using our security wrapper they saw the light and included it (properly) in the core libraries. Of course they could have included security as part of their remit but they didn't see the point.

    ReflectionTestUtils.setField() .... is about the only other legitimate use. Just saying.

  • nasch (unregistered)

    "so long as the unit tests can run without making changes to the production database."

    If a test is connecting to an actual database, it isn't a unit test.

  • masterX244 (unregistered) in reply to Naomi

    Does loading of Plugins count, too?

  • Some Ed (unregistered) in reply to Nick

    I find it interesting that your bafflement of unit tests that exist in a production environment went on to explain how it is that unit tests would be safe to have in a production environment.

    To be precise, a proper unit test does not talk to a database, full stop, so it won't make changes to the production environment. It simply runs the code, with any necessary mocking needed to simulate databases, to see what it would do in very specific, static cases.

    The static nature of those cases is one of their downsides, as it's easy to miss updating all of the unit tests to reflect changes in the environment. Many review processes won't catch these, as they focus on what's changing, and the unit tests that aren't changing are, by definition, not changing. But the chief advantage is that they run in controlled situations without making permanent changes, except possibly to a scratch folder, and validate whether or not your code does what you intended when you last updated the unit test. They're usually pretty quick to run, since things that take a long time to run tend to take a lot of setup time, and unit tests are supposed to be as low maintenance as feasible.

Leave a comment on “Reaching for Private Parts”

Log In or post as a guest

Replying to comment #:

« Return to Article