Bug 516377 - [9] Add more attributes to module-info.class
Summary: [9] Add more attributes to module-info.class
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.7   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: BETA J9   Edit
Assignee: Stephan Herrmann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 518445 498983
  Show dependency tree
 
Reported: 2017-05-09 14:08 EDT by Stephan Herrmann CLA
Modified: 2017-09-09 16:31 EDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Stephan Herrmann CLA 2017-05-09 14:08:07 EDT
ecj doesn't yet support these class file attributes
 - ModulePackages
 - ModuleMainClass

The former needs a full scan of the module.
The latter requires additional input / user selection.

=> Should both be added (only) when exporting as a modular jar file? That would be bug 498983 in JDT/UI

Let's use this bug for providing API to generate module-info.class with that additional info provided by the caller.
Comment 1 Sarika Sinha CLA 2017-08-08 02:22:17 EDT
When can we expect this feature?
Comment 2 Stephan Herrmann CLA 2017-08-19 17:00:10 EDT
Well, generating one or two more attributes shouldn't be difficult. I'm just not sure about the best protocol for this.

From a quick scan it looks like this would be consumed in or around org.eclipse.jdt.ui.jarpackager.JarWriter3 ?

E.g., addFile(IFile resource, IPath path) could intercept the file "module-info.class", ask JDT/Core to recompile with additional properties, where JDT/Core could answer the byte[] that the packager can insert into the JarOutputStream.

Or, the jar packager could trigger compilation with properties up-front, maybe, initially we still have the source file module-info.java? Would be more convenient for JDT/Core.

JarFileExportOperation.exportJavaElement(IProgressMonitor, IJavaElement) still knows about JavaElements, which would facilitate interfacing with JDT/Core.

Would s.t. like this be OK:

  byte[] JavaCore.compileWithAttributes(IModuleDescription module, Map<String,String> classFileAttributes)

?
Should we be more specific about the attribute names?

Should the API accept source & binary modules? (In the binary cause it would be Core's responsibility to map back to the source for recompilation).

I'm pretty sure we will not store the modified .class on disk, because we don't want to interfere with the builder etc.

Perhaps, JarFileExportOperation does the communication with JDT/Core and prepares a replacement map, that can be passed into JarWriter3?
Comment 3 Stephan Herrmann CLA 2017-08-20 15:17:49 EDT
FWIW, adding these attributes after the fact and with no support from the JDK has been discussed recently on jigsaw-dev: http://mail.openjdk.java.net/pipermail/jigsaw-dev/2017-August/013099.html - not that it would help us, though.
Comment 4 Sarika Sinha CLA 2017-08-21 04:57:13 EDT
(In reply to Stephan Herrmann from comment #2)
> Well, generating one or two more attributes shouldn't be difficult. I'm just
> not sure about the best protocol for this.
> 
I will check and get back on this.
Comment 5 Sarika Sinha CLA 2017-09-04 05:56:24 EDT
API looks ok.
byte[] JavaCore.compileWithAttributes(IModuleDescription module, Map<String,String> classFileAttributes)

Just to confirm, so the Map classFileAttributes will expect the attribute name ModulePackages and ModuleMainClass as keys and values as null?

?
>Should we be more specific about the attribute names?
If JDT Core wants to keep the API generic, JDT UI can pass the attribute name. Are you foreseeing other scenarios ?

>Should the API accept source & binary modules? (In the binary cause it would be Core's responsibility to map back to the source for recompilation).
I am not sure about binary requirement, are you aware any scenario which requires it.

>I'm pretty sure we will not store the modified .class on disk, because we don't >want to interfere with the builder etc.

Yes, makes sense.

>Perhaps, JarFileExportOperation does the communication with JDT/Core and >prepares a replacement map, that can be passed into JarWriter3?

Looks doable.
Comment 6 Stephan Herrmann CLA 2017-09-05 09:33:46 EDT
(In reply to Sarika Sinha from comment #5)
> API looks ok.
> byte[] JavaCore.compileWithAttributes(IModuleDescription module,
> Map<String,String> classFileAttributes)
> 
> Just to confirm, so the Map classFileAttributes will expect the attribute
> name ModulePackages and ModuleMainClass as keys and values as null?

I didn't think about the values, but now that you are asking:
- ModulePackages: yes, passing value = null signals to Core: please compute
- ModuleMainClass: I'd expect UI to pass this from the wizard (Core doesn't know)
 
Put differently, if we receive name x value, then we simply put it into the class file without thinking twice. If the name is ModulePackages and the value is null, we will compute the packages.

To communicate that Core has special knowledge about ModulePackages I will provide a constant for this, for use by clients.

> >Should we be more specific about the attribute names?
> If JDT Core wants to keep the API generic, JDT UI can pass the attribute
> name. Are you foreseeing other scenarios ?

I was thinking of future addition of more attributes, as the language evolves. Generic API avoids the necessity to add new API each time.


> >Should the API accept source & binary modules? (In the binary cause it would be Core's responsibility to map back to the source for recompilation).
> I am not sure about binary requirement, are you aware any scenario which
> requires it.

Think of a project from binary class folders, which you don't have the sources of (e.g., extracted from a jar), which now you want to repackage just to add the new attributes. Thinking more about it, if you already have module-info.class it's not very likely s.o. still wants to add attributes to it.
=> Let's not worry about this right now.
Comment 7 Sarika Sinha CLA 2017-09-05 12:23:34 EDT
Sounds good!!
Comment 8 Stephan Herrmann CLA 2017-09-07 16:04:14 EDT
Now that we have an agreement, I plan to work on this over the weekend.
Comment 10 Eclipse Genie CLA 2017-09-09 14:54:12 EDT
New Gerrit change created: https://git.eclipse.org/r/104801
Comment 11 Stephan Herrmann CLA 2017-09-09 15:07:25 EDT
(In reply to Eclipse Genie from comment #10)
> New Gerrit change created: https://git.eclipse.org/r/104801

@Sarika, this should do the trick. There are minor modifications in the protocol, please see the javadoc of the new method in JavaCore. Let me know if anything is unclear, or doesn't work for you.


For ModuleMainClass I also provided an alternative mechanism: this can now be specified using a classpath attribute on the source folder holding module-info.java. :) In this case every compilation of this module will create the classfile attribute.

I thought of this as the cheapest option for making this parameter persistent in the project.

Still, the new API can specify the main class, which would overrule the classpath attribute, if set.
Comment 13 Stephan Herrmann CLA 2017-09-09 16:31:41 EDT
(In reply to Eclipse Genie from comment #12)
> Gerrit change https://git.eclipse.org/r/104801 was merged to [BETA_JAVA9].
> Commit:
> http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=6f90d44d90811c036e9a1d93a1138bbc37f8d26b
> 

Released for BETA_JAVA9