Is signing a plaintext sufficient? If I have N bytes of plaintext, does signing it with my private key prove (to holders of my public key) that I have signed that exact plaintext messages?

i.e. could an attacker use the plaintext and signature to generate another plaintext which would also verify?

Or do I need to hash the plaintext to provide message integrity?
A signature algorithm should - in general - be thought to contain the hashing method as parameter. Take for instance RSA / PSS. RSA / PSS includes the  EMSA-PSS-ENCODE operation. Here the hash function to use is an option to the algorith.

Step 2 is:


  Let mHash = Hash(M), an octet string of length hLen.


where M is the message to be signed.



"Or do I need to hash the plaintext to provide message integrity?" is therefore a question that is non-sensical for most signature definitions. RSA has deprecated modes that directly sign a message (with message recovery) but those are generally not used. ECDSA is also defined for use with a hash function and EC crypto cannot easily "encrypt the message" with the private key for signature generation.



As you have found out, Signature dsa = Signature.getInstance("SHA256withECDSA"); uses SHA-256 as an option to ECDSA. The hashing will then be performed internally.

Sometimes hash value or intermediate hash value is used as input for signature generation. This can be useful when the device that performs the private key generation is limited in hashing bandwith. E.g. for a smart card you may not want to send all the data to the smart card - sending just the hash is much more efficient.