ChatGPT解决这个技术问题 Extra ChatGPT

IntelliJ IDEA generating serialVersionUID

How do generate this value in IntelliJ IDEA?

I go to Settings -> Errors -> Serialization issues -> Serializable class without ‘serialVersionUID’, but it still doesn't show me the warning. My class PKladrBuilding parent implements interface Serializable.

Part of the code:

public class PKladrBuilding extends PRQObject

public abstract class PRQObject extends PObject

public abstract class PObject implements Serializable
Are you sure you need to generate a value, rather than defining your own? If you are creating a new class, I would recommend you define e.g. 1L as your ID and increment when your serialized form changes. (See stackoverflow.com/questions/888335/…).
stackoverflow.com/questions/24573643/… has a very good solution.

P
Peter Mortensen

I am not sure if you have an old version of IntelliJ IDEA, but if I go to menu File → Settings... → Inspections → Serialization issues → Serializable class without 'serialVersionUID'` enabled, the class you provide give me warnings.

https://i.stack.imgur.com/lpmCC.png

If I try the first class I see:

https://i.stack.imgur.com/zb5lI.png

BTW: It didn't show me a warning until I added { } to the end of each class to fix the compile error.


Try File | Invalidate Caches, if it doesn't help, contact support@jetbrains.com with a sample project to reproduce.
Check idea.log (Help | Reveal Log in ...) for exceptions, encrypted home directory on Linux is known to cause problems because of the kernel bug.
i have a lot of exceptions there.. like java.lang.NoClassDefFoundError: org/intellij/lang/annotations/MagicConstant;
I have reinstalled IDEA and removed plug-ins and it helps me. Tnx a lot.
The way I got it working in the v15 is to hover over the ClassName to see the warning and move my mouse slowly towards the gutter. At that point the "lightbulb" shows up on the screen. (Try this a few times if it does not work as intended the first time). Then you can click on the create field option to create the uid. Hope this helps people who are stuck on this.
P
Peter Mortensen

Install the GenerateSerialVersionUID plugin by Olivier Descout.

Go to: menu FileSettingsPluginsBrowse repositoriesGenerateSerialVersionUID

Install the plugin and restart.

Now you can generate the id from menu Code → Generate → serialVersionUID` or the shortcut.


Should one require an external plugin really in order to get this working?
Yes you need a plugin which is already part of IntelliJ plugin repository.
Timeout for me on Android Studio
Works in 2017.3.4 - I noticed you could not generate a serialVersionUID when it was defined in a base class (even though it is private static and should not matter in that sense). This plugin just offered the option and works. Nice.
Answer is correct, but a plugin which breaks every few major version is not as good as using the internal solution also posted here.
N
Nikhil Katre

Without any plugins: You just need to enable highlight in IntelliJ:

IntelliJ Preferences -> Editor -> Inspections -> Java -> Serialization issues -> Serializable class without 'serialVersionUID' - set flag and click 'OK'.

Now, if your class implements Serializable, you will see highlight, and alt+Enter on class name will propose to generate private static final long serialVersionUID.

PS: Taken from here


Thanks. I don't know why I don't see the light bulb, but clicking on the class name and typing Alt-Enter does the trick.
Answer is stolen from here
this is more uptodate
E
Emdadul Sawon

After spending some time on Serialization, I find that, we should not generate serialVersionUID with some random value, we should give it a meaningful value.

Here is a details comment on this. I am coping the comment here.

Actually, you should not be "generating" serial version UIDs. It is a dumb "feature" that stems from the general misunderstanding of how that ID is used by Java. You should be giving these IDs meaningful, readable values, e.g. starting with 1L, and incrementing them each time you think the new version of the class should render all previous versions (that might be previously serialized) obsolete. All utilities that generate such IDs basically do what the JVM does when the ID is not defined: they generate the value based on the content of the class file, hence coming up with unreadable meaningless long integers. If you want each and every version of your class to be distinct (in the eyes of the JVM) then you should not even specify the serialVersionUID value isnce the JVM will produce one on the fly, and the value of each version of your class will be unique. The purpose of defining that value explicitly is to tell the serialization mechanism to treat different versions of the class that have the same SVUID as if they are the same, e.g. not to reject the older serialized versions. So, if you define the ID and never change it (and I assume that's what you do since you rely on the auto-generation, and you probably never re-generate your IDs) you are ensuring that all - even absolutely different - versions of your class will be considered the same by the serialization mechanism. Is that what you want? If not, and if you indeed want to have control over how your objects are recognized, you should be using simple values that you yourself can understand and easily update when you decide that the class has changed significantly. Having a 23-digit value does not help at all.

Hope this helps. Good luck.


Thanks, I was skipping this simple fact for so long time!
I actually would re-generate the serialVersionUID with a new random number when I don't want to support old versions on deserialization. Maybe I don't need to use random numbers but can start with 1 and increment it. However, 3L doesn't have more meaning to me then -3518231192373568183L. Therefore, I guess both solutions work similarly. The random number might have the advantage that it woks on non-linear histories with forks and branches, though.
p
pharsfalvi

In order to generate the value use

private static final long serialVersionUID = $randomLong$L;
$END$

and provide the randomLong template variable with the following value: groovyScript("new Random().nextLong().abs()")

https://pharsfalvi.wordpress.com/2015/03/18/adding-serialversionuid-in-idea/


love this comment, using live templates this is for sure the fastest solution and most customisable (I removed the newline for example). To configure go to Android Studio > Preferences > Editor > Live Templates and create a new one there (plus icon) with this value and use edit variables to enter the script
a
acdcjunior

In addition you can add live template that will do the work.

To do it press Ctrl+Alt+S -> "Live Templates" section -> other (or w/e you wish)

And then create a new one with a definition like this:

private static final long serialVersionUID = 1L;
$END$

Then select definition scope and save it as 'serial'

Now you can type serialTAB in class body.


j
jeremysprofile

Easiest modern method: Alt+Enter on

private static final long serialVersionUID = ;

IntelliJ will underline the space after the =. put your cursor on it and hit alt+Enter (Option+Enter on Mac). You'll get a popover that says "Randomly Change serialVersionUID Initializer". Just hit enter, and it'll populate that space with a random long.


A
Alexander

Another way to generate the serialVersionUID is to use >Analyze >Run Inspection by Name from the context menu ( or the keyboard short cut, which is ctrl+alt+shift+i by default) and then type "Serializable class without 'serialVersionUID'" (or simply type "serialVersionUID" and the type ahead function will find it for you.

https://i.stack.imgur.com/mRT0u.png

With this approach you don't even have to set the general inspection rules to anything.


Nice, this did the job for me. It found the missing variable and presented the option to add it.
Q
Quoc Nguyen

With version v2018.2.1

Go to

Preference > Editor > Inspections > Java > Serialization issues > toggle "Serializable class without 'serialVersionUID'".

A warning should appear next to the class declaration.


J
Johnny Wu

I am using Android Studio 2.1 and I have better consistency of getting the lightbulb by clicking on the class Name and hover over it for a second.


P
Peter Mortensen

If you want to add the absent serialVersionUID for a bunch of files, IntelliJ IDEA may not work very well. I come up some simple script to fulfill this goal with ease:

base_dir=$(pwd)
src_dir=$base_dir/src/main/java
ic_api_cp=$base_dir/target/classes

while read f
do
    clazz=${f//\//.}
    clazz=${clazz/%.java/}
    seruidstr=$(serialver -classpath $ic_api_cp $clazz | cut -d ':' -f 2 | sed -e 's/^\s\+//')
    perl -ni.bak -e "print $_; printf qq{%s\n}, q{    private $seruidstr} if /public class/" $src_dir/$f
done

You save this script, say as add_serialVersionUID.sh in your ~/bin folder. Then you run it in the root directory of your Maven or Gradle project like:

add_serialVersionUID.sh < myJavaToAmend.lst

This .lst includes the list of Java files to add the serialVersionUID in the following format:

com/abc/ic/api/model/domain/item/BizOrderTransDO.java
com/abc/ic/api/model/domain/item/CardPassFeature.java
com/abc/ic/api/model/domain/item/CategoryFeature.java
com/abc/ic/api/model/domain/item/GoodsFeature.java
com/abc/ic/api/model/domain/item/ItemFeature.java
com/abc/ic/api/model/domain/item/ItemPicUrls.java
com/abc/ic/api/model/domain/item/ItemSkuDO.java
com/abc/ic/api/model/domain/serve/ServeCategoryFeature.java
com/abc/ic/api/model/domain/serve/ServeFeature.java
com/abc/ic/api/model/param/depot/DepotItemDTO.java
com/abc/ic/api/model/param/depot/DepotItemQueryDTO.java
com/abc/ic/api/model/param/depot/InDepotDTO.java
com/abc/ic/api/model/param/depot/OutDepotDTO.java

This script uses the JDK serialVer tool. It is ideal for a situation when you want to amend a huge number of classes which had no serialVersionUID set in the first place while maintain the compatibility with the old classes.


P
Peter Mortensen

Add a live template called "ser" to the other group, set it to "Applicable in Java: declaration", and untick "Shorten FQ names". Give it a template text of just:

$serial$

Now edit variables and set serial to:

groovyScript("(System.env.JDK_HOME+'/bin/serialver -classpath '+com.intellij.openapi.fileEditor.FileDocumentManager.instance.getFile(_editor.document).path.replaceAll('/java/.*','').replaceAll('/src/','/build/classes/')+' '+_1).execute().text.replaceAll('.*: *','')",qualifiedClassName())

It assumes the standard Gradle project layout. Change /build/ to /target/ for Maven.