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 237156 - Lombok: Organzie members causing havoc!
Summary: Lombok: Organzie members causing havoc!
Status: RESOLVED WONTFIX
Alias: None
Product: java
Classification: Unclassified
Component: Hints (show other bugs)
Version: 8.0
Hardware: PC Windows 8 x64
: P4 normal with 1 vote (vote)
Assignee: Svata Dedic
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-10-15 19:39 UTC by akobberup
Modified: 2013-10-16 14:37 UTC (History)
1 user (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
ide-log (329.75 KB, text/plain)
2013-10-15 19:39 UTC, akobberup
Details

Note You need to log in before you can comment on or make changes to this bug.
Description akobberup 2013-10-15 19:39:04 UTC
Created attachment 141112 [details]
ide-log

It seems that "organize members" can have a hard time not destroying a class that contains a lot of annotations. Invoking organizing members on this class:

--------------------------------------------------------------------------------
package org.and.logbook.data.persistent.hibernate;

import javax.persistence.AttributeOverride;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.and.logbook.data.persistent.Login;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;

@Entity
@Table(name = "Login")
@DynamicInsert(true)
@DynamicUpdate(true)
@AttributeOverride(name = "id", column = @Column(name = "LoginId"))
@Getter
@Setter
@AllArgsConstructor
public class LoginImpl extends BasePersistentEntity implements Login {
	private static final long serialVersionUID = 2L;

	@Column(name="Identifier")
	private String identifier;

	@Column(name="Password")
	private String password;

	protected LoginImpl() {
		//for hibernate
	}
}

--------------------------------------------------------------------------------

will make it look like this:
--------------------------------------------------------------------------------

package org.and.logbook.data.persistent.hibernate;

import javax.persistence.AttributeOverride;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.and.logbook.data.persistent.Login;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;

@Entity
@Table(name = "Login")
@DynamicInsert(true)
@DynamicUpdate(true)
@AttributeOverride(name = "id", column = @Column(name = "LoginId"))
@Getter
@Setter
@AllArgsConstructor
public class LoginImpl extends BasePersistentEntity implements Login {
	private static final long serialVersionUID = 2L;@AllArgsConstructor
public class LoginImpl extends BasePersistentEntity implements Login {
	private static final long serialVersionUID = 2L;

	@Column(name="Identifier")
	private String identifier;@AllArgsConstructor
public class LoginImpl extends BasePersistentEntity implements Login {
	private static final long serialVersionUID = 2L;

	@Column(name="Identifier")
	private String identifier;

	@Column(name="Password")
	private String password;

	protected LoginImpl() {
		//for hibernate
	}
AllArgsConstructor
public class LoginImpl extends BasePersistentEntity implements Login {
	private static final long serialVersionUID = 2L;

	@Column(name="Identifier")
	private String LoginImpl	@Column(name="Password", ) package org.and.logbook.data.persistent.hibernate;

import javax.persistence.AttributeOverride;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.and.logbook.data.persistent.Login;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;

@Entity
@Table(name = "Login")
@DynamicInsert(true)
@DynamicUpdate(true)
@AttributeOverride(name = "id", column = @Column(name = "LoginId"))
@Getter
@Setter
@AllArgsConstructor
public class LoginImpl extends BasePersistentEntity implements Login {
	private static final long serialVersionUID = 2L;

	@Column(name="Identifier")
	private String identifier;

	@Column(name="Password")@AllArgsConstructor
public class LoginImpl extends BasePersistentEntity implements Login {
	private static final long serialVersionUID = 2L;

	@Column(name="Identifier")
	private String identifier;

	@Column(name="Password")
	private String getIdentifier	protected LoginImpl() package org.and.logbook.data.persistent.hibernate;

import javax.persistence.AttributeOverride;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.and.logbook.data.persistent.Login;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;

@Entity
@Table(name = "Login")
@DynamicInsert(true)
@DynamicUpdate(true)
@AttributeOverride(name = "id", column = @Column(name = "LoginId"))
@Getter
@Setter
@AllArgsConstructor
public class LoginImpl extends BasePersistentEntity implements Login {
	private static final long serialVersionUID = 2L;

	@Column(name="Identifier")
	private String @All package org.and.logbook.data.persistent.hibernate;

import javax.persistence.AttributeOverride;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.and.logbook.data.persistent.Login;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;

@Entity
@Table(name = "Login")
@DynamicInsert(true)
@DynamicUpdate(true)
@AttributeOverride(name = "id", column = @Column(name = "LoginId"))
@Getter
@Setter
@AllArgsConstructor
public class LoginImpl extends BasePersistentEntity implements Login {
	private static final long serialVersionUID = 2L;

	@Column(name="Identifier")
	private String identifier;

	@Column(name="Password")
	private String sepackage org.and.logbook.data.persistent.hibernate;

import javax.persistence.AttributeOverride;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.and.logbook.data.persistent.Login;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;

@Entity
@Table(name = "Login") package org.and.logbook.data.persistent.hibernate;

import javax.persistence.AttributeOverride;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.and.logbook.data.persistent.Login;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;

@Entity
@Table(name = "Login")
@DynamicInsert(true)
@DynamicUpdate(true)
@AttributeOverride(name = "id", column = @Column(name = "LoginId"))
@Getter
@Setter
package org.and.logbook.data.persistent.hibernate;

import javax.persistence.AttributeOverride;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.and.logbook.data.persistent.Login;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;

@Entity
@Table(name = "Login")
@DynamicInsert(true)
@DynamicUpdate(true)
@AttributeOverride(name = "id", column = @Column(name = "LoginId"))
@Getter
@Setter
	 sepackage org.and.logbook.data.persistent.hibernate;

import javax.persistence.AttributeOverride;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.and.logbook.data.persistent.Login;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;

@Entity
@Table(name = "Login")
	package org.and.logbook.data.persistent.hibernate;

import javax.persistence.AttributeOverride;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.and.logbook.data.persistent.Login;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;

@Entity
@Table(name = "Login")
@DynamicInsert(true)
@DynamicUpdate(true)
@AttributeOverride(name = "id", column = @Column(name = "LoginId"))
@Getter
@Setter
@AllArgsConstructor
public class LoginImpl extends BasePersistentEntity implements Login {
	private static final long serialVersionUID = 2L;

	@Column(name="Identifier")
	private String identifier;

	@Column(name="Password")
	private String password;

	protected LoginImpl() {
		//for hibernate
	}
}

--------------------------------------------------------------------------------
Comment 1 akobberup 2013-10-16 09:20:27 UTC
To test this, please note that a new lombok version has been released a few days ago that support java 8. Use this, otherwise NB dont run the preprocessor (as nb editor internally use java 8 compiler).


<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.12.2</version>
</dependency>
Comment 2 akobberup 2013-10-16 09:26:55 UTC

Simple test class:
--------------------------------------------------------------------------------
@lombok.Data
public class TestOrg {
	String string;
}
--------------------------------------------------------------------------------
running format members will jumble it into this:
--------------------------------------------------------------------------------
@lombok.Data
public class TestOrg {
	String string;@lombok.Data
public class TestOrg {
	String string;
}string;
} string;
} @lombok.Data
public class TestOrg {
	String string;
}@lombok.Data
public class TestOrg {
	String string;
}@lombok.Data
public class TestOrg {
	String string;
}@lombok.Data
public class TestOrg {
	String string;
}
--------------------------------------------------------------------------------
Comment 3 Svata Dedic 2013-10-16 12:24:06 UTC
The model produced by Lombok annotation processor should perhaps conform to some conventions, so Lombok-introduced symbols could be avoided. The ClassTree for example contain all the generated members without any flag that would allow to classify them as synthetic or generated/not present in the source file. The MethodTree for e.g. getString() getter even contains positional info suggesting a valid place in the source file. Neither SYNTHETIC or GENERATEDCONSTR flags are present on that method.

I admit there is probably no JSR or a de-facto standard specification on ann. processor's behaviour with respect to tools operating on sources, but I might be mistaken. If such a generic guideline is available && Lombok adheres to it, please link it and reopen the defect. Given the supposed adoption of Lombok and the stats on GitHub, I am decreasing priority to address the supposed affected user base. 
The actual resulting behaviour is a defect, but not caused by NetBeans' handling - rather Lombok's inappropriate interference with NetBeans processing. It's very likely other source-processing tools would have similar problems.

Note that I will not implement any Lombok-specific processing in NB-8 timeframe (other priorities are set up) and will not suggest to focus on Lombok-specific behaviour in coming future given e.g. the gap NetBeans still has in static analysis (overall better to focus brain-time there). The decision is likely to be revisited after the major user base's needs are covered.
Lombok developers should either invent a compatible way to produce the generated content, or provide appropriate code for tools they declare support for.

Patches are, obviously, welcomed as zero to minimal resources or core development (see above) would be consumed that way.
Comment 4 Michel Graciano 2013-10-16 14:37:22 UTC
I have a issue at Lombok side related to it: https://code.google.com/p/projectlombok/issues/detail?id=591