This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 254955 - static imports of methods are being duplicated without reason
Summary: static imports of methods are being duplicated without reason
Status: RESOLVED FIXED
Alias: None
Product: java
Classification: Unclassified
Component: Refactoring (show other bugs)
Version: 8.1
Hardware: PC Windows 7 x64
: P2 normal with 5 votes (vote)
Assignee: Svata Dedic
URL:
Keywords:
: 258058 268148 (view as bug list)
Depends on:
Blocks:
 
Reported: 2015-09-03 07:40 UTC by Marian Petras
Modified: 2016-11-15 19:20 UTC (History)
5 users (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
binary patch for NetBeans 8.1 (35.96 KB, application/octet-stream)
2016-04-25 07:05 UTC, Marian Petras
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Marian Petras 2015-09-03 07:40:22 UTC
When I edit a Java file that contains static imports of methods (e.g. java.lang.Math.min), these static imports are being duplicated without any apparent reason.

In the file, I have several non-static imports and several static imports. Among the static imports, most are used for constants (enum values) and the last one is for java.lang.Math.min. The import for java.lang.Math.min is being duplicated as I edit the file, although I do not modify the part of code (method) where the imported method "min" is used.

I usually notice the duplicates when an editor hint appears ("Import section does not correspond to the specified code style rules").

This issue is new in version 8.1 - it did not happen in previous versions.

--
Product Version: NetBeans IDE 8.1 Beta (Build 201508041349)
Java: 1.8.0_60; Java HotSpot(TM) 64-Bit Server VM 25.60-b23
Runtime: Java(TM) SE Runtime Environment 1.8.0_60-b27
System: Windows 7 version 6.1 running on amd64; Cp1250; cs_CZ (nb)
Comment 1 Dusan Balek 2015-09-03 07:49:18 UTC
Exact steps to reproduce would be more than welcome.
Comment 2 Marian Petras 2015-09-03 08:30:46 UTC
I will try to find some simple steps to reproduce.

For now, I can only say that the file is in an EJB module of a Java EE 7 application (I do not know if that matters).
Comment 3 Marian Petras 2015-09-16 11:34:43 UTC
This happens during refactoring, e.g. renaming a field or a method parameter.
Comment 4 Marian Petras 2015-10-01 13:38:38 UTC
Duplicite static imports are added even to source files that have not been open in the editor.

The last time it happened, the scenario was as follows:

I develop a Java EE application that uses (among others) the following three Java SE libraries:

   Utils - contains utility methods, one of them is named ArgUtils
   Persistence - contains JPA entities, one of them is named SomeEntity
   Filter - contains some filter classes (the semantics is not relevant),
            one of them is named SomeFilter

Class ArgUtils contains a utility (public static) method checkArgNotNull(...).

Class SomeEntity imports the utility method and also defines several constants:

    package persistence;

    ...
    import static util.ArgUtils.checkArgNotNull;
    ...

    public class SomeEntity {

        public static final String CONST1 = "value1";
        public static final String CONST2 = "value2";
        public static final String CONST3 = "value3";

        public static final String ANOTHER_CONSTANT = "anotherValue";

        ...

    }

Class SomeFilter does not define any public constants (defines just 'serialVersionUID') but imports class SomeEntity, uses one of the public constants defined in class SomeEntity and also imports the same utility method:

    package filter;

    ...
    import persistence.SomeEntity;
    ...
    import static util.ArgUtils.checkArgNotNull;
    ...

    public class SomeFilter {

        public void someMethod() {
            ...
            callAnotherMethod(SomeEntity.ANOTHER_CONSTANT, ...);
            ...
        }

    }

Then, when I renamed the constants CONST1, CONST2 and CONST3 (using refactoring), seven duplicates of static import util.ArgUtils.checkArgNotNull were added to each of the above classes (SomeEntity, SomeFilter). The duplicite imports were appended to the end of the block of static imports:

    ...
    import static util.ArgUtils.checkArgNotNull;
    import static foo.bar.AnotherUtilClass.anotherMethod;
    import static util.ArgUtils.checkArgNotNull;
    import static util.ArgUtils.checkArgNotNull;
    import static util.ArgUtils.checkArgNotNull;
    import static util.ArgUtils.checkArgNotNull;
    import static util.ArgUtils.checkArgNotNull;
    import static util.ArgUtils.checkArgNotNull;
    import static util.ArgUtils.checkArgNotNull;

There were multiple static imports used in each of the above classes, but ArgUtils.checkArgNotNull was the only static import used in both classes.

The static import ArgUtils.checkArgNotNull is used in many other classes but the duplicite imports were added only to these two classes (to one where I applied the refactoring and to one using a constant from a refactored class).
Comment 5 Marian Petras 2015-11-11 08:52:53 UTC
The number of duplicite imports added can be big.

Just a minute ago I asked NetBeans to rename a private field together with a corresponding getter and NetBeans added 4600 duplicite imports to a single class:

import static java.lang.Integer.parseInt;
import static java.util.regex.Pattern.compile;
import static java.lang.Integer.parseInt;
import static java.util.regex.Pattern.compile;
import static java.lang.Integer.parseInt;
import static java.util.regex.Pattern.compile;
import static java.lang.Integer.parseInt;
import static java.util.regex.Pattern.compile;
...


Regarding steps to reproduce:

Just rename some fields or methods in a class with static imports and you will soon see it happens.
Comment 6 Marian Petras 2015-11-11 11:11:35 UTC
It seems that if some imports get duplicated as a result of refactoring, then the number of duplicates gets doubled with each refactoring operation. As a result, the number of imports grows exponentially with the number of refactoring operations.
Comment 7 jinahya 2015-11-15 12:36:59 UTC
I have 4 thousands lines of

    import static java.util.logging.Logger.getLogger;
Comment 8 Leperous 2015-11-17 15:32:53 UTC
I can reproduce this always in a vanilla JavaSE/Maven project simply by invoking the "rename field" popup.

Consider the following class:

import static java.util.Objects.requireNonNull;

public class Test {
   
    final int number;
    
    public Test(final Integer number) {
        this.number = requireNonNull(number);
    }

}

If you refactor the "number" field, for example by changing its name, then the static import is duplicated. In fact, it is doubled every time!
Comment 9 jessholle 2016-02-18 13:55:25 UTC
This is a *really* annoying bug.  I have to go fix all my imports after doing a refactoring.

We have Maven build steps to fail the build when messed up imports like this are encountered.  That's good in that such a mess is cleaned up right away, but it's bad that I have to manually clean up after NetBeans here!
Comment 10 Marian Petras 2016-02-21 21:38:02 UTC
According to bug #258058, this happens when renaming a class with overloaded static imports.
Comment 11 Marian Petras 2016-02-21 21:41:44 UTC
*** Bug 258058 has been marked as a duplicate of this bug. ***
Comment 12 matthies 2016-02-23 19:38:52 UTC
This bug causes serious problems. I've had cases where repeated refactorings (like renaming methods and static constants) caused thousands of static imports to accrue in various classes. In one case, I found 24576 static imports in one class, due to three static imports being multiplied 8192 times, likely as the result of 13 refactorings (8192 = 2^13). The problem is that the duplications potentially arise in all source files affected by a refactoring, and so can accumulate invisibly all around the code base.

A large number of static imports, in turn, causes Find Usages as well as further refactorings to require a very large (exponential?) amount of heap memory. In one medium-sized code base I maintain, the amount required quickly exceeded the available heap memory (I stopped increasing JVM heap space at 8GB), leading to excessive GC and heap memory errors, and practically freezing NetBeans. The only solution to make Find Usages and refactorings work again was to search through all source files and remove the extraneous static imports. Of course, new refactorings again cause the duplication of static imports, so it's a repeating problem.

I verified that this bug is a regression from NetBeans 8.0.1. Due to the severity and recurrence of the problems it causes, I'm increasing the priority to P2.
Comment 13 Svata Dedic 2016-03-01 15:28:47 UTC
Seems as refactoring issue. WorkingCopy gets a new compilation unit with duplicated import.
Comment 14 Ralph Ruijs 2016-03-03 11:42:04 UTC
changeset:   54b295f06b79
user:        Ralph Benjamin Ruijs <ralphbenjamin@netbeans.org>
date:        Thu Mar 03 12:39:55 2016 +0100
summary:     #254955 - static imports of methods are being duplicated without reason
Comment 15 Quality Engineering 2016-03-04 02:07:07 UTC
Integrated into 'main-silver', will be available in build *201603040002* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)

Changeset: http://hg.netbeans.org/main-silver/rev/54b295f06b79
User: Ralph Benjamin Ruijs <ralphbenjamin@netbeans.org>
Log: #254955 - static imports of methods are being duplicated without reason
Comment 16 Marian Petras 2016-04-25 07:05:12 UTC
Created attachment 159418 [details]
binary patch for NetBeans 8.1

The binary patch (patch-254955.jar) contains bytecode (.class files) of the patched class (RenameTransformer).
To apply it, put the file to subdirectory

    java/modules/patches/org-netbeans-modules-refactoring-java

of the NetBeans installation directory (e.g. C:\Program Files\NetBeans 8.1). For more information about using binary patches, see http://wiki.netbeans.org/DevFaqModulePatching.

It is quite probable that subdirectory

    patches/org-netbeans-modules-refactoring-java

does not exist. The solution is simple - create it.

If the patch is recognized and used by NetBeans, it writes the following line to the IDE Log (to see the log, select View->IDE Log from the NetBeans menu):

    INFO [org.netbeans.core.startup.NbEvents]: Module patch or custom extension: C:\Program Files\NetBeans 8.1\java\modules\patches\org-netbeans-modules-refactoring-java\patch-254955.jar

I have been using the patch for several weeks and it works for me - no more duplicite imports. However, it as an unofficial patch (I am not an Oracle employee) so use it at your own risk.
Comment 17 jessholle 2016-04-25 11:13:51 UTC
Recently there were a number of updates to core NetBeans modules/plugins.

I'd hoped/expected that this would automatically be included in that number.

I take it from the last comment that this was not the case (I've not yet had a chance to check this out).  Given that this fix was in place since 3/4, I don't get why this wasn't part of the next set of core plugin updates.
Comment 18 Marian Petras 2016-04-25 20:56:10 UTC
Jess, I don't know whether any of the NetBeans updates fixed this bug. I just realized that the attached binary patch has been working well for me and so it might be useful for others, too.

If the bug gets fixed in some official update, I would expect at least a note of the fact here in the Bugzilla.
Comment 19 sjaak 2016-06-09 16:13:40 UTC
+1 for this one.. I've spent a day of searching on this one. patch works as a breeze. Can you include it in the main development stream?
Comment 20 jinahya 2016-07-27 07:30:56 UTC
Please reopen this issue. I'm still seeing this behavio(u)r with 8.1
Comment 21 Svata Dedic 2016-07-27 07:42:19 UTC
(In reply to jinahya from comment #20)
> Please reopen this issue. I'm still seeing this behavio(u)r with 8.1

Please read this report carefully. 
The bug was discovered in 8.1 and FIXED for the next dev version, that is upcoming 8.2. Reopening the defect has no effect since 8.2 release is planned for autumn. The bug is already marked as patch-candidate, so if an unlikely patch release is created, this bug should be included.
Comment 22 _ wadechandler 2016-09-15 11:56:17 UTC
There is another component to this as well in that scanning will freak out and flood the logs with

 INFO [null]: Last record repeated again.

and then eat up 100% of CPU eventually, and take a very long time to complete, and then too, all actions waiting on scans are them blocked...like renaming a field. The user then doesn't know why this is happening. I made a wild guess after a git diff, removed the extra duplicate imports, of which I had many, as I was adding a prefix to a group of statics, and then scanning was still broken. I then removed my cache directory entirely, with the indexes, and restarted NB, and then things were manageable. Anyways, this exploits some other issue. I think the steps to reproduce are:

1. create a class with multiple static imports on the tail of the import list; I'm using RestAssured for testing, and had many many static imports which were each being repeated; important the imports are on the tail it seems
2. create a base class which the class with many static imports extends.
3. Add static imports to the base class, but make sure they are on the tail of the imports; seems to only affect those; I had 1 at the top I noticed in the base class, and then multiple at the bottom/tail of the imports.
4. Add a number, say 30 static variables to the base class.
5. Start adding an arbitrary prefix to those static variables with CTRL-R or rename refactoring; keep changing the variable names as needed and watch it slow down.
6. Eventually scanning should become slower and slower as you'll see "Preparing" takes longer. Finally you'll see that even waiting on the refactoring rename dialog to popup takes a very long time. Then if background scanning kicks in during this scenario, you are hosed. It will take so long you'll stop the IDE. Then the index seems to become buggered.

This looks like an opportunity to track down some of that "scanning takes forever" stuff perhaps too.
Comment 23 hans_adler 2016-11-15 19:20:08 UTC
*** Bug 268148 has been marked as a duplicate of this bug. ***