So, I have a large project that serializes many things when saving a configuration, and had to do a re-design of a large section of it. Since I had already defined the serialVersionUID field for a lot of classes, I wanted to know which files I needed to re-calculate the UID for.
I couldn't find any post on SO about what properties of a class were used in the calculation of the serialVersionUID (via ObjectStreamClass.lookup(classname) ). I finally found the spot in the spec that defines it. So, this is more of one of those self-answering questions for the sake of saving this small piece of knowledge.
If this is out-of-etiquette (since it is a spec question) please let me know, I'll gladly remove it or whatever is SO-appropriate.
So, what particulars of a class are used when using the Java-built-in algorithm of calculating a serialVersionUID?
It's detailed right here in the Java spec!
http://docs.oracle.com/javase/6/docs/platform/serialization/spec/class.html#4100
Does anybody know if it's different based on different implementations/utilities? (Such as via ObjectStreamClass.lookup vs. serialver utility?)
Related
First of all this might be a dumb question and I searched for some days but didn't find an answer. So if there is an existing answer concerning my question, I would be grateful for a link.
I don't know if anyone of you ever coded Spigot, Paper or Bukkit, but there was a class called YamlConfiguration which had the following methods:
public FileConfiguration cfg = YamlConfiguration.loadConfiguration(file);
cfg.set(path.path2, "hello");
cfg.getInt/String/...(path.path2); (which obviously returns "hello")
cfg.save(file);
The produced file then looks like this:
path:
path2: "hello"
So you could basically save any value in those files and reuse them even if your program has been restarted.
I know have moved forward from Spigot/Paper to native Java and I'm missing something like that Yaml-thing. The only thing I found was a kind of a config file, where every time the whole file is overwritten, when I try to add values.
Can you show me a proper way of saving values to a file? (would be nice without libraries)
I'm missing sth like that Yaml-thing
SnakeYAML should have you covered. Without knowing anything about your use-case, it makes no sense to discuss its usage here since its documentation already does cover the general topics.
The only thing I found was a kind of a config file, where everytime the whole file is overwritten, when I try to add values.
Saving as YAML will always overwrite the complete file as well. Serialization does not really work with append-only. (Serialization is the term to search for when you want functionality like this, by the way.)
If you mean that previous values were deleted, that probably was because you didn't load the file's content before or some other coding error, but since you don't show your code, we can only speculate.
Can you show me a proper way of saving values to a file?
People will have quite different opinions on what would be a proper way and therefore it is not a good question to ask here. It also heavily depends on your use-case.
would be nice without libraries
So you're basically saying „previously I used a library which had a nice feature but I want to have that feature without using a library“. This stance won't get you far in today's increasingly modular software world.
For example, JAXB which offers (de)serialization from/to XML was previously part of Java SE, but has been removed as of Java SE 11 and is a separate library now.
When I first started using the Java Preferences API, the one glaring omission from the API was a putObject() method. I've always wondered why they did not include it.
So, I did some googling and I found this article from IBM which shows you how to do it: http://www.ibm.com/developerworks/library/j-prefapi/
The method they're using seems a bit hackish to me, because you have to break the Object up into byte matrices, store them, and reassemble them later.
My question is, has anyone tried this approach? Can you testify that it is a good way to store/retrieve objects?.
I'm also curious why the Java devs left putObject() out of the API. Does anyone have valuable insight?
I'm also curious why the Java devs left putObject() out of the API.
Does anyone have valuable insight?
From: http://docs.oracle.com/javase/7/docs/technotes/guides/preferences/designfaq.html
Why doesn't this API contain methods to read and write arbitrary
serializable objects?
Serialized objects are somewhat fragile: if the version of the program
that reads such a property differs from the version that wrote it, the
object may not deserialize properly (or at all). It is not impossible
to store serialized objects using this API, but we do not encourage
it, and have not provided a convenience method.
The article describes a reliable way to do it. I see there are a couple of things I may do differently (like I would store the count of the number of pieces as well as the pieces themselves so that I can figure things out easily when I retrieve them).
Your comment about Serialization is wrong though.... the object you want to store has to be Serializable.... that's how the ObjectOutputStream that the document uses does it's job.
So, Yes, it looks like a reliable mechanism, you need to have Serializable objects, and I imagine that the reason that putObject and getObject are not part of the API for two reasons:
it's not part of the way that is native to Windows registries
It risks people putting huge amounts of data in the registry.
Storing serialized objects in the registry strikes me as being somewhat concerning because they can be so big. I would only use it for occasions when there is no way to reconstruct the Object from constructors, and the serialized version is relatively small.
Is there any diff tool specifically for Java that doesn't just highlight differences in a file, but is more complex?
By more complex I mean it'd take 2 input files, the same class file of different versions, and tell me things like:
Field names changed
New methods added
Deleted methods
Methods whose signatures have changed
Methods whose implementations have changed (not interested in any more detail than that)
Done some Googling and can't find anything like this...I figure it could be useful in determining whether or not changes to dependencies would require a rebuild of a particular module.
Thanks in advance
Edit:
I suppose I should clarify:
I'm not bothered about a GUI for the tool, it'd be something I'm interested in calling programmatically.
And as for my reasoning:
To workout if I need to rebuild certain modules/components if their dependencies have changed (which could save us around 1 hour per component)... More detailed explanation but I don't really see it as important.
To be used to analyse changes made to certain components that we are trying to lock down and rely on as being more stable, we are attempting to ensure that only very rarely should method signatures change in a particular component.
You said above that Clirr is what you're looking for.
But for others with slightly differet needs, I'd like to recommend JDiff. Both have pros and cons, but for my needs I ended up using JDiff. I don't think it'll satisfy your last bullet point and it's difficult to call programmatically. What it does do is generate a useful report for API differences.
I recently read an article talking about the Java annotations, and on this latter comes the #Generated one. They say that it is used for automatically generate code.
Could someone explain me that in further with a little example ?
All what i found on the net was some pro question or something beyond what i was looking for.
As per the JavaDoc:
The Generated annoation is used to mark source code that has been generated. It can also be used to differentiate user written code from generated code in a single file.
#Generated is used by meta-programs such as Auto/Value which generate source code so you don't have to manually write it. If you're writing a .java file by hand (which is normally what one does), don't use #Generated.
Fox example are good and bad policies on the border between generated and written code. Way of thinking is (i belive) different in compiled (static) languages, nad interpreted / dynamic.
Worst is to modify generated code (will be lost at next generation, or next generation is then prohibited)
Usually is accepted to derive (manual) class from generated, or generate class what extends core "manual" class.
If someone know good policies in this area, please comment.
Some code linters use the annotation to skip generated code. For example, it doesn't make sense to calculate cyclomatic complexity on generated code.
For example:
Security.setProperty("ocsp.enable", "true");
And this is used only when a CertPathValidator is used. I see two options for imporement:
again singleton, but with getter and setter for each property
an object containing the properties relevant to the current context:
CertPathValidator.setValidatorProperties(..) (it already has a setter for PKIXParameters, which is a good start, but it does not include everything)
Some reasons might be:
setting the properties from the command line - a simple transformer from command-line to default values in the classes suggested above would be trivial
allowing additional custom properties by different providers - they can have public Map getProviderProperties(), or even public Object .. with casting.
I'm curious, because these properties are not always in the most visible place, and instead of seeing them while using the API, you have to go though dozens of google results before (if lucky) getting them. Because - in the first place - you don't always know what exactly you are looking for.
Another fatal drawback I just observed is that this is not thread-safe. For example if two threads want to check a revocation via ocsp, they have to set the ocsp.responderURL property.. and perhaps override the settings of each other.
This is actually a great question that forces you to think about design decisions you may have made in the past. Thanks for asking a question that should have occurred to me years ago!
It sounds like the objection is not so much the singleton aspect of this (although an entirely different discussion could occur about that) - but the use of string keys.
I've worked on APIs that used this sort of scheme, and the reasons you outline above were definitely the driving factors - it makes it crazy simple to parse a command line or properties file, and it allows for 3rd party extensibility without impact to the official API.
In our library, we actually had a class with a bunch of static final String entries for each of the official parameters. This gave us the best of both worlds - the developer could still use code completion where it made sense to do so. It also becomes possible to construct hierarchies of related settings using inner classes.
All that said, I think that the first reason (easy parsing of command line) doesn't really cut it. Creating a reflection driven mechanism for pushing settings into a bunch of setters would be fairly easy, and it would prevent the cruft of String->object transformation from drifting into the main application classes.
Extensibility is a bit trickier, but I think it could still be handled using a reflection driven system. The idea would be to have the main configuration object (the one with all the setters in it) also have a registerExtensionConfiguration(xxx) method. A standard notation (probably dot separated) could be used to dive into the resultant acyclic graph of configuration objects to determine where the setter should be called.
The advantage of the above approach is that it puts all of the command line argument/properties file parsing exception handling in one place. There isn't a risk of a mis-formatted argument floating around for weeks before it gets hit.