| Summary: | Wizard for creating EGL external types for Java classes | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Product: | z_Archived | Reporter: | Will Smythe <smythew> | ||||||||||||||||
| Component: | EDT | Assignee: | Zhi Zhu <zhuzhi> | ||||||||||||||||
| Status: | CLOSED FIXED | QA Contact: | |||||||||||||||||
| Severity: | enhancement | ||||||||||||||||||
| Priority: | P1 | CC: | chenzhh, jvincens, mayunf, mheitz, pharmon, svihovec, tdramsey, tww | ||||||||||||||||
| Version: | unspecified | ||||||||||||||||||
| Target Milestone: | --- | ||||||||||||||||||
| Hardware: | PC | ||||||||||||||||||
| OS: | Windows XP | ||||||||||||||||||
| Whiteboard: | |||||||||||||||||||
| Bug Depends on: | 370533 | ||||||||||||||||||
| Bug Blocks: | 354668, 373350, 373373 | ||||||||||||||||||
| Attachments: |
|
||||||||||||||||||
|
Description
Will Smythe
Zhi is full time on 8013 SVT, so move this out of I1. Thanks. This is one of the main themes for the .8 release. Related Enhancements: 354667 and 354668 From my understanding, when defining an external type, constructor for the external type is not indispensable, does the EGL compiler provide a default one when external type has no constructor, similar to Java? These questions came from an e-mail thread, I putting them here to involve everyone associated with this enhancement. What can the user select before starting the wizard, a class, a class in a jar, a java source? Most eclipse views don't show the class files. Should the user be able to select a Java source file and start the wizard? Can the user select a class file that is in a jar file? Reply to comment 4: Yes, if you don't define a constructor in the ET, then we use a constructor with no arguments. In general, we need to remember why we are considering this line item in the first place, which is to enable users with existing Java code to easily integrate that code with their EGL application. I assume this means that users will want to integrate Java code from the current EDT project (i.e. JAR file), or from other projects in their workspace (i.e. JAR file, .java, required plug-ins, etc). While the wizard can be invoked from multiple types of input, I am thinking that the underlying code will eventually operate on .class files, so hopefully starting from a .java file does not add much over head. If a user does select a file from another project, we should consider how the EDT project containing the ET needs to be configured so that the required .class file can be found at runtime. This could involve adding the required .java files directly to the EDT project, or adding classpath entries to the EDT project (and possibly a JavaNature, etc). I would think that Java Mail discussion in this forum post - https://www.ibm.com/developerworks/forums/thread.jspa?messageID=14772630� would be a good green thread on the JAR requirement. A .java green thread could involve a separate Java project with a Java class that uses the same Java Mail classes from the first Green Thread, and some additional hand written Java classes. This would be a good test for configuring the EDT project with the ET to find these required .class files at runtime, whether this needs to be done manually by the user, or if it is done automatically by the wizard. I disagree with the direction we're going in. When you start the wizard, the current selection in the Project Explorer or Navigator should be used to initialize the project and package of the .egl file for the ExternalType being created. That's what we do for our other wizards. And we shouldn't make people hunt for a .java, .class, or .jar file. There have been many times when I wanted to examine a class and I didn't know where it came from. So I just did Open Type and entered its name. I propose that the wizard's first page lets you choose the EGL project, package, and file name for the new .egl file. Fill in defaults for the project and package if possible, based on the selection in the Project Explorer or Navigator. The first page also lets you choose the Java class using the Open Type API. Additional choices can be specified on subsequent pages. I think I agree with Matt :). I envisioned the developer supplying/selecting the EGL package and EGL part name (like our other wizards), but then browsing for the Java class to create the external type for. I would go so far as to say this Java class would need to be in the classpath of the EGL project where the new EGL part is being created. The developer would get a dialog (like the Open Type) dialog and it would show all Java classes in a list. Only actual classes would be shown - regardless of whether that class existed in a JAR or as a compiled Java file. I am fine with placing the class selection mechanism 'inside' the External Type wizard, and I think that requiring the class to already be on the project path will make the wizard easier to implement. I have attached two screen captures from JDT wizards that I think are relevant. 1) New Class Wizard - The new class wizard provides a mechanism for entering a type name, with content assist, and a browse button that opens the 'Open Type' dialog. 2) Implements Method - This is the JDT mechanism for adding methods to a class based on the interfaces that the class implements. In the case of the External Type wizard, the 'methods to implement' are defined in the selected Java class and its hierarchy. Created attachment 210329 [details]
Screen Captures
Created attachment 210355 [details]
Design Draft
Will,Brian,Mat and Joe, I have drafed the design for this enhancement, please review it and see whether it misses requirement items. Another question: Does the wizard need to generate external type for java.lang.Object? For this question from Will: would we need/want to also generate external types for classes referenced by this class? How deep would we need/want to go? In my view external types for all referenced classes should be generated, what's your view for it? (In reply to )
> EDT enhancement 366480 and 354667 and 354668 are related, discussed this with
> Joe, he thought all of them should be treated as enhancements for generating
> external type from Java class, what's your opinion about this?
Since 354667 is no longer relevant I have closed it. You still need to handle classes in jars so 354668 is still relevant, if you consider it part of this task you can resolve it as closed.
(In reply to comment #15) > For this question from Will: would we need/want to also generate external types > for classes referenced by this class? How deep would we need/want to go? > > In my view external types for all referenced classes should be generated, > what's your view for it? I think we should give the user a choice. Sometimes I make an ET so I can call one static method. Making ETs for all referenced classes is too much. But there are other times when I want to work with the Java objects a lot, so I want ETs for the referenced classes. In my original proposal for the wizard, I mentioned a checkbox for "Make ExternalTypes for all superclasses, interfaces, and superinterfaces." I also mentioned a choice to make ETs from the classes referenced by the selected class. That would be a checkbox too. (In reply to comment #14) > Another question: Does the wizard need to generate external type for > java.lang.Object? Yes. Object has public methods that people might want to use (hashCode, toString, equals). If we use the suggestions I made in comment #17, and the user checks the box to make ETs for all superclasses etc., then we would make an ET for Object. (In reply to comment #12) > Created attachment 210355 [details] > Design Draft Here are my comments on the design document. Page 2 says "let one select which methods or fields to be generated." Also let users select constructors of the class, but not any constructors of its superclasses. Be sure they can select methods and fields that are static. We should only let them select fields, methods, and constructors that are public. You asked if the wizard should generate one EGL file containing all external types or one EGL file for each external type. I'd prefer one file for all external types, but I think this is another place where we could give the user a choice. However, this choice is probably the least important aspect of the wizard. If we're looking for ways to save time we could implement it later. (Also, consider that on the first page of the wizard users can choose the name for the first ET's file. If we make one file for each ET, I assume users would not get to choose the names for the files of the other ETs. That's a little inconsistent.) The design looks good. I have the following comments:
* The document should indicate that the Browse for type button will only show Java classes on the classpath of the current project.
* It would be good if you could provide a sketch of the External Type for Java Class wizard page so that we have an idea how you think it will look (something hand drawn in MS Paint would be fine)
* Will we always add a '?' for Java types that extend from Object in fields, parameters, and return types?
* Will we allow users to choose what EGL primitive types to insert for fields, parameters, and return types? (i.e. a Java method that returns 'String' or 'int')
* The JS External Types defined for Widget specify the Property annotation:
x Int { @Property { getMethod="getX", setMethod="setX" } };
We may want the wizard to be able to do this as well for the Java Class external type page, but this can be a future enhancement.
Two more things... (Note: here I'm using "supertypes" to mean "interfaces, supertypes, and superinterfaces.") 1. We don't want ET creation to get out of control. If you choose to make ETs for the supertypes, and also to make ETs for referenced types, I don't think we should make ETs for the referenced types of the supertypes. 2. I just thought of an entirely new approach for dealing with supertypes. Rather than make separate ETs for them, would could merge their APIs into one big ET. For example, a "merged ET" for java.util.HashSet would include methods & fields from classes HashSet, AbstractSet, AbstractCollection, and Object, plus interfaces Set, Iterable, Collection, Serializable, and Cloneable. (This list comes from http://docs.oracle.com/javase/6/docs/api/java/util/HashSet.html) Joe tells me that he has a utility for converting Java classes into .ir files containing External Types. I think we should try to re-use this utility, but I also think we need to go further and create EGL Source files for these External Types, so that users can change the ET after it has been created, and so that they have something to commit to a source control system. In the past, I believe Tony worked on a utility for converting .ir files into EGL source, so maybe we could combine these two utilities with the wizard front end to achieve our goal. (In reply to comment #21) > Two more things... > > (Note: here I'm using "supertypes" to mean "interfaces, supertypes, and > superinterfaces.") > > 1. We don't want ET creation to get out of control. If you choose to make ETs > for the supertypes, and also to make ETs for referenced types, I don't think we > should make ETs for the referenced types of the supertypes. > > 2. I just thought of an entirely new approach for dealing with supertypes. > Rather than make separate ETs for them, would could merge their APIs into one > big ET. For example, a "merged ET" for java.util.HashSet would include methods > & fields from classes HashSet, AbstractSet, AbstractCollection, and Object, > plus interfaces Set, Iterable, Collection, Serializable, and Cloneable. (This > list comes from > http://docs.oracle.com/javase/6/docs/api/java/util/HashSet.html) For question 1: Generating ETs for required referenced types is not optional to avoid EGL validation error; for example, If we generate ET for java.io.FileInputStream, and select constructor: public FileInputStream(File file) , we also need generating ET for class File; as for referenced types of the supertypes, if related parts of supertypes are not selected, no ETs will be generated for them; otherwise should generate ETs for them. For question 2: If we merge them into one class; we cannot reuse generated ETs; but it is a way we can try. Created attachment 210423 [details]
Update design doc based on feedback
(In reply to comment #23) > For question 1: Generating ETs for required referenced types is not optional > to avoid EGL validation error; for example, If we generate ET for > java.io.FileInputStream, and select constructor: public FileInputStream(File > file) > , we also need generating ET for class File; as for referenced types of the > supertypes, if related parts of supertypes are not selected, no ETs will be > generated for them; otherwise should generate ETs for them. I might already have an ET for File. > For question 2: If we merge them into one class; we cannot reuse generated > ETs; but it is a way we can try. Yes. It's not what I would prefer. The updated design looks good. Questions/Comments: * What type of error will we display if the currently selected EGL project does not have the Java nature? * What type of message will appear if there are no Java classes on the classpath? * Will we filter out the EGL Java Generation folder so that we do not show those classes as options in the Type view? * As mentioned in the New Service wizard (367261), we should look at the EGL2Java code and other examples in the SQL Record wizard template and re-use code where possible for converting Java code to EGL source. * Should we include another wizard page, that does not have to be visited, to provide a list of all External Types we are about to create, including a number, so that users can see how their selections will affect the number of ET's created? (In reply to comment #26) > The updated design looks good. > > Questions/Comments: > * What type of error will we display if the currently selected EGL project does > not have the Java nature? --- Display a message to indicate this. > * What type of message will appear if there are no Java classes on the > classpath? --- Since we will use a dialog similar to 'Open Type' to select a class, if there are no Java classes on the classpath, one can select nothing. > * Will we filter out the EGL Java Generation folder so that we do not show > those classes as options in the Type view? --- Yes, will filter out EGL Java Generation folder > * As mentioned in the New Service wizard (367261), we should look at the > EGL2Java code and other examples in the SQL Record wizard template and re-use > code where possible for converting Java code to EGL source. --- Yes, try to reuse existing codes as more as possible > * Should we include another wizard page, that does not have to be visited, to > provide a list of all External Types we are about to create, including a > number, so that users can see how their selections will affect the number of > ET's created? --- Will provide a Summary page for this, similar to record/handler wizard. Who will provide icons for External Type Wizard and toolbar? Created attachment 210484 [details]
More Update
We should validate the current design/thinking by coming up with a few common/ examples of Java APIs that people will want to access. For example, we should confirm stuff like javax.mail (http://javamail.kenai.com/nonav/javadocs/javax/mail/package-summary.html) can be integrated in and called from EGL. Matt H may have some good ideas about other Java libraries that we expect people to want to access from EGL. externalType exTT type JavaObject{JavaName = "externalTypeName", PackageName = "packageName"}
end
has compilation error, then how to write external type in EDT?
depends on bug 370533 (In reply to comment #31) > externalType exTT type JavaObject{JavaName = "externalTypeName", PackageName = > "packageName"} > end > > has compilation error, then how to write external type in EDT? In EDT we replaced JavaName with externalName. (And ETs for JavaScript also have externalName, in place of JavaScriptName.) Brian & Matt: In FileInputStream class, we have close() method, when we generate egl for this method, compiler indicates that 'close' is a reserved word for EGL and cannot be used as method name, how do we deal with the scenario? thanks Zhi, I would bring this issue up in the CDL Scrum meeting. I believe other developers on the CDL team have already resolved this issue for existing wizards. Also, if there are any updates to the original design, can you attach them to this defect? (In reply to comment #34) > In FileInputStream class, we have close() method, when we generate egl for > this method, compiler indicates that 'close' is a reserved word for EGL and > cannot be used as method name, how do we deal with the scenario? Zhi, You can put the externalName annotation on the function. In the example below I named the function "_close", but the generated code will call it "close" because of its externalName. ExternalType FileInputStream type JavaObject { packageName = "java.io" } function _close() { externalName = "close" }; end You can also use externalName on a field. -Matt thanks for your update. Basically I am developing based on our design, after completing coding, I will update the design doc and attach it. Created attachment 211783 [details]
code for this feature
Will & Brian & Matt:
I have completed most of the part of the feature, you can download the patch and have a try and look forward to your feedback.
Also I encounter a problem:
Now I can generate external types from java class file, but if I write a Java source file and put it under 'src' package, still have problem loading the class:
I use ReflectionUtil.getClass(String fullyQualifiedName)
But ClassNotFound exception is rolled back, I have tried other ways, but not succeed at all, do you have any suggestions for this
Zhi, Either you're not using the fully-qualified name for the class you're trying to load, or the class isn't in your classpath. Check the project's Java Build Path. Also, haven't reviewed your patch except to look at ReflectionUtil.getClass(). You should add a catch block for LinkageError, since Class.forName() can throw those. (It can also throw an ExceptionInInitializerError, which is a subclass of LinkageError, so catching LinkageError will handle both.) -Matt Created attachment 211857 [details]
New Patch
Matt: thanks for your feedback, I resolved the class loading problem. Matt, if you have time, could you review the code and have a try with the Wizard and provide your feedback on them. thanks Created attachment 211934 [details]
Patch based on Justin's feedback
Check in code and resolve the enhancement. From Brian: I discussed with type issues with the team, and we believe that in the .8 time frame, we should disallow users from creating External Types fro a class if the class uses (directly or indirectly): Bytes,Char,or Array I'm reopening this because the work mentioned in comment 45 is not yet done. By the way, the end of comment 45 should say "we should disallow users from creating External Types from a class if the class uses (directly or indirectly): byte, char, or any kind of array". At the moment, the wizard creates an EGL array from a Java array. For example: public class Foo { public int[] z; } externalType Foo type JavaObject z int[]; end That's wrong (EGL arrays will map to Java Lists, not Java arrays), so this needs to be fixed in I3. The rest of the work (don't make an ET if it uses byte or char) could be done after I3 if you want. Just leave this bug open and change the target milestone to 0.8.0 Final. (In reply to comment #46) So, what should an java int[] be mapped to in EGL? Should this just be treated like the other un-mappable types like byte and char? Filter out field whose type is Array, filter out any method/constructor whose parameter is any kind of array since EGL does not support array directly close it |