[HN Gopher] JEP Draft: Integrity and Strong Encapsulation
       ___________________________________________________________________
        
       JEP Draft: Integrity and Strong Encapsulation
        
       Author : mfiguiere
       Score  : 40 points
       Date   : 2023-04-19 17:44 UTC (5 hours ago)
        
 (HTM) web link (openjdk.org)
 (TXT) w3m dump (openjdk.org)
        
       | deepzn wrote:
       | Well written case. But quite a long read, the first JEP Draft I
       | read though, wasn't expecting it.
        
       | _old_dude_ wrote:
       | That's a lot of lines to say that dynamically loadable agents
       | will not be enable by default in Java 21 [1].
       | 
       | I suppose it's to avoid sneaky libraries that dynamically starts
       | an agent to crack open the code of the JDK.
       | 
       | [1] https://bugs.openjdk.org/browse/JDK-8306275
        
       | w10-1 wrote:
       | fyi, JEP status dashboard:
       | https://bugs.openjdk.org/secure/Dashboard.jspa?selectPageId=...
        
       | quantumwoke wrote:
       | As the maintainer of a large piece of Java software that
       | interacts with legacy code in over 50% of the codebase, this was
       | a very scary read. It sounds like the entire basis for my
       | software which tens of thousands of people rely on every day is
       | soon to be "restricted". I cannot prepare my users for the fact
       | that my software _will not work with no recourse_ in the future.
       | I understand the JVM's need for safety, but this is personally
       | destroying my livelihood. It's along the lines of telling Ruby
       | users one day that monkey patching will be phased out in the next
       | release.
       | 
       | I suppose the next layer down the chain is to start patching code
       | with ASM. Ugh.
        
         | blibble wrote:
         | the entire low latency sector is will be stuck on java 8 until
         | they figure out what they're going to do with Unsafe
         | 
         | which may be forever
        
         | Pet_Ant wrote:
         | The old JVMs will still be available and you so will the Docker
         | containers with them.
         | 
         | That said the writing has been on the wall since Java 9's
         | project Jigsaw. If you have a product that depends on it, I'm
         | surprised you were caught unaware. With more control over what
         | is exported, the amount of compiler optimisations possible
         | greatly increases.
        
           | quantumwoke wrote:
           | Not if the software I depend on requires the latest JVM
           | (which it will).
        
             | Pet_Ant wrote:
             | Well they have you covered:
             | 
             | > To balance the need for integrity with both the
             | circumstantial, convenience uses of JDK internals and the
             | essential uses, Java gives the user - the application's
             | owner (typically its author, maintainer, or deployer) - the
             | final say on which strong encapsulation boundaries are in
             | place and which should be ignored. This freedom is offered
             | under the guiding principle that the ability of one
             | component to encroach on the boundaries of another must be
             | explicitly granted by the application. Libraries cannot
             | choose to obtain encapsulation-busting "superpowers"
             | without the knowledge and consent of the application's
             | owner.
        
             | geodel wrote:
             | Well new JVM rules comes with new JVM. So something gotta
             | give. Leaving Java be potentially unsafe just because few
             | customer relied on it would be irresponsible behavior on
             | JDK maintainers part.
        
               | exabrial wrote:
               | I'm not sure how current JVMs are "unsafe" though. If you
               | go messing with the internals of third party classes,
               | seems like any consequences should be obvious.
        
               | tsimionescu wrote:
               | > If you go messing with the internals of third party
               | classes, seems like any consequences should be obvious.
               | 
               | The point made in the article is that it's often third-
               | party libraries that do this, breaking invariants in your
               | code. And, with older JVMs, it won't be immediately
               | obvious to you as a user of that library that this is
               | happening.
        
               | exabrial wrote:
               | I can't recall a time when 3rd party code has changed
               | something in my code and broke it. I was hoping someone
               | could provide me with an example
        
               | kaba0 wrote:
               | Then just enable it at start time with a flag.
        
         | amluto wrote:
         | It sounds like --add-opens, etc will still exist. Can you use
         | that? It would, as discussed, be an admission of legacy-ness.
        
         | JanecekPetr wrote:
         | > "will not work with no recourse"
         | 
         | No, the CLI `--add-opens` CLI option will stay. In other words,
         | applications will need to consciously enable the encapsulation-
         | breaking stuff. Is that bad? Modern software moved to public
         | APIs quite a bit ago. That said, if old applications want to
         | use new JDKs, they will require quite some developement, yes.
        
       | yarg wrote:
       | So what's the solution to deserialization?
       | 
       | He mentioned the Even class, but there didn't seem to be anything
       | that looked to fix the lack of validation when reading from JSON?
       | 
       | If it's out of scope, why bring it up without mentioning further
       | work (or am I missing something)?
        
         | tadfisher wrote:
         | The solution is code generation, which is more performant and
         | less brittle than maintaining runtime reflection machinery to
         | break encapsulation. Moshi is a good example of a library that
         | does this.
        
         | mrkeen wrote:
         | (My words, not the article's)
         | 
         | The fix is to go through the front door, not the back door.
         | 
         | Whatever deserialisation library/technique you use, it should
         | have to use constructors just like everyone else, because
         | that's where you can put your logic to make sure all your
         | invariants hold.
        
           | gizmo686 wrote:
           | The problem is Java's Serializable interface, which is a core
           | part of the language. To the extent that it is implemented
           | with VM black magic, and has an entire keyword (transient) in
           | the languages syntax to support it.
           | 
           | It is possible to provide your own (de)serialization logic,
           | and so you could, in principle, enforce your invariant there.
           | Unfortunately, to provide custom logic you implement:
           | private void writeObject(ObjectOutputStream)         private
           | void readObject(ObjectInputStream)
           | 
           | Notably, the deserialization method is not a constructor,
           | which causes problems if you have final fields.
           | 
           | You can use the defaultReadObject method to invoke the JVM
           | black magic, then perform your own invariant checks, but you
           | need to know to do this. When the alternative of adding
           | 'implements serializable' you will likely have developers
           | forget that they need to add the checks.
           | 
           | On the glass half full side, at least classes need to opt in
           | to serializeability. There is another universe, where classes
           | are serializable by default.
           | 
           | Having said all of this, Java's serializable is a massive
           | security hole that should never be given untrusted input.
        
       | exabrial wrote:
       | First, not to sound ungrateful, I appreciate everything over at
       | OpenJDK does and thank them for being excellent stewards of the
       | ecosystem. Their fair and balanced approach, while putting
       | backwards compatibility at the forefront, is something very rare
       | these days.
       | 
       | > Legacy bugs have been fixed so it is exceptionally rare to need
       | to break encapsulation to work around them.
       | 
       | I do think their line of thinking is quite optimistic. Take this
       | famous bug: https://bugs.openjdk.org/browse/JDK-8207840 which was
       | set to Resolved, Won't Fix and instead the recommend a newer API.
       | Here's the thing, a lot of third party code still uses the older
       | API. A major use case is attempting to call the SalesForce API
       | using HTTPUrlConnection or a library that wraps this class...
       | Good luck. Despite SalesForce being extraordinarily common, you
       | simply can't call it using the JDK's standard classes as the SF
       | API required HTTP PATCH.
       | 
       | The only workaround we can find, save building/patching an entire
       | JDK, is at Runtime, to do some dirty things to the JDK with the
       | Reflection and/or Unsafe APIs. We'd love to migrate every app to
       | the latest JDK where HTTP PATCH might be supported, but
       | RuntimePatching allows us to not have to cross that bridge.
       | 
       | As a matter of fact, we have a JVM Agent that intercepts class
       | loads and can patch 3rd Party Libraries on the fly. This allows
       | us to immediately deploy fixes to prod when things like
       | Spring4Shell appear.
        
         | deepzn wrote:
         | oh wow, the JVM agent usecase is pretty cool, maybe unsafe, but
         | still. The war for safety vs flexibility.
        
       ___________________________________________________________________
       (page generated 2023-04-19 23:02 UTC)