Lombok: Feature request: abbreviated package names

Created on 14 Jul 2015  路  11Comments  路  Source: projectlombok/lombok

_Migrated from Google Code (issue 290)_

accepted enhancement

Most helpful comment

Any news on this feature? I would love to see this in lombok!

All 11 comments

:bust_in_silhouette: [email protected]   :clock8: Oct 18, 2011 at 19:14 UTC

It would be nice if lombok provided a way to abbreviate package names, so that classes with a duplicate name but in different packages could more easily be used together.

For example, say I have code that uses both com.google.common.base.Predicate and org.apache.commons.collections.Predicate. I can only import one of them, so the other class name must be spelled out long-form every time.

Ideally, I would like to be able to say "google.Predicate" or "apache.Predicate" and then have lombok rewrite that into the full package name. I expect to have to write down a "google => com.google.common.base" or "google.Predicate => com.google.common.base.Predicate" annotation rule somewhere for lombok to know what to do. Given that teams should probably strive to use the same abbreviations from one file to the next anyway, an annotation on a package-info.java file seems like a good way to specify the abbreviation mappings, which could them be used within all code in that package.

This problem is really a failing of the Java language's "import" syntax (no "namespace aliasing" or "import as", but it does cause the occasional headache and seems worth thinking about a fix for, at least.

Note that at runtime, I still do want the full (com.google...) name to be used, so the various jar-repacking techniques aren't the right fix here.

:bust_in_silhouette: reinierz   :clock8: Oct 25, 2011 at 07:12 UTC

Looking for config info such as these package shorthand mappings anywhere but the source file itself is extremely problematic. It can be done, but the last time we introduced features that did this is over a year ago and we're still cleaning up bugs related to how complicated things get when we look outside of source.

I'm fairly sure we don't want that burden for this feature, so it would have to be local to each file, and then I'm not sure how much boilerplate you really save.

Let's revisit this when we have a config framework in place, preferably one project-wide.

:bust_in_silhouette: r.spilker   :clock8: Oct 25, 2011 at 07:52 UTC

We might be able to do it in a local file, as long as the import is a fully qualified name. Then wherever you must* use a type you can specify it by any unique part.

import com.google.common.base.Predicate;
import org.apache.commons.collections.Predicate;

class Foo implements google.Predicate {

}

class Bar implements collections.Predicate {
}

  • Since java uses the . for packace separator, class name separator, enum constant separator and field separator, it's still hard to make this work and would require either resolution or depending on casing.

:bust_in_silhouette: grootjans   :clock8: Nov 07, 2011 at 21:28 UTC

We think this might be a nice feature, so we proposed an initial syntax on the forums:
http://groups.google.com/group/project-lombok/t/db9ff859978d710f

We still have to hash out the syntax, and see if we can really make this work in javac and Eclipse.

:bust_in_silhouette: askoning   :clock8: Oct 07, 2013 at 17:22 UTC

Issue #619 has been merged into this issue.

_End of migration_

Any news on this feature? I would love to see this in lombok!

I would like to propose another way of implementing this (in style of val and var). In my opinion code looks even nicer:

New annotation:

public @interface alias {

}

Code with Lombok:

package org.example.view;

import org.example.domain.model.Employee;

interface EmployeeMapper {
  EmployeeView map(Employee employee);
  Employee map(EmployeeView view);

  static alias EmployeeView = org.example.view.model.Employee.class;
}

Delomboked:

package org.example.view;

import org.example.domain.model.Employee;

interface EmployeeMapper {
  org.example.view.model.Employee map(Employee employee);
  Employee map(org.example.view.model.Employee view);

  static @alias EmployeeView = org.example.view.model.Employee.class;
}

BTW. I've posted a JEP to OpenJDK on aliasing (JEP draft can be seen here: https://gist.github.com/cardil/b29a81efd64a09585076fe00e3d34de7), but I don't have high hope that Oracle change their minds on this.

@cardil
I'm afraid, with

static alias EmployeeView = org.example.view.model.Employee.class;

the compiler would abort before even calling Lombok (the parser would complain). It'd probably have to look like

@alias interface EmployeeView extends org.example.view.model.Employee.class {}

so that it comes through.

However, for naming consistency, I'd suggest not to support anything on the class level.


@rzwitserloot

Let's revisit this when we have a config framework in place, preferably one project-wide.

Now we do. I'd suggest a simple syntax like

typeAliases+=EmployeeView->org.example.view.model.Employee
typeAliases+=base.Predicate->com.google.common.base.Predicate

which would make Lombok unconditionally replace all occurrences. No resolution and no complicated logic. This can lead to naming conflicts, but let's say, it's user's responsibility to choose a globally usable shortcut.

@Maaartinus Ups. I think you are right about my idea. It needs a bit of tweaking.

About project wide config solution. I really hate this global approach - I will not use it as it is dangerous. That will defeats whore purpose. You want to have those aliases private, used only in parts of the code that meets with similar domains - that is only in Mappers. Everywhere else there shouldn't be those aliases. It shouldn't be global.

I think it better should be like this.

New annotation:

public @interface Alias {
}

Code with Lombok:

package org.example.view;

import org.example.domain.model.Employee;

interface EmployeeMapper {
  EmployeeView map(Employee employee);
  Employee map(EmployeeView view);

  // to alias class
  @Alias
  class EmployeeView extends org.example.view.model.Employee {}
  // or to alias interface
  @Alias
  interface EmployeeView extends org.example.view.model.Employee {}
}

Delomboked:

package org.example.view;

import org.example.domain.model.Employee;

interface EmployeeMapper {
  org.example.view.model.Employee map(Employee employee);
  Employee map(org.example.view.model.Employee view);

  @Alias
  class EmployeeView extends org.example.view.model.Employee {}
}

It will be limited to non final classes and interfaces.

I will not use it as it is dangerous.

IMHO, it's not dangerous at all, when used sparingly and properly reviewed. I'd only use it for classes having a name conflicting with something else or legacy classes like

awt.List = java.awt.List
obsol.JulDate = java.util.Date
obsol.SqlDate = java.sql.Date

and forbid myself ever importing them. This would be actually safer than the current state.


Your use case is clearly different. Actually, I try hard to avoid having two equally named classes in my projects - I use a lot of class nesting and funny prefixes/suffixes, but I can see why you do not.

You want to have those aliases private, used only in parts of the code that meets with similar domains - that is only in Mappers.

  • Actually, lombok.config applies to a whole subdirectory, i.e., to a package and its subpackages. This may be local enough for you.
  • I guess, any top-level definition in *.java can only be applied to the current file only as inspecting other files is rather impossible.
  • For the start, I'd forbid nesting alias definitions as it's probably rarely needed.

It will be limited to non final classes and interfaces.

Not necessarily..... the parser doesn't care and maybe Lombok can do its job before it blows. It can probably do the replacement and remove the alias declaration.


The remaining problem is the implementation..... more precisely, an implementer is needed. I hope, the project maintainers (not me) say what they think about the syntax and whether a PR is welcome (I'm pretty busy and hacking Lombok is hard).

Oracle implementing your JEP would be best.

Was this page helpful?
0 / 5 - 0 ratings