Home » Modeling » EMF » getting started with JETEmitter
| getting started with JETEmitter [message #377594] |
Tue, 20 May 2003 20:14  |
|
Originally posted by: remko.popma.azzurri.jp
This is a multi-part message in MIME format.
------=_NextPart_000_0036_01C31F79.5DDE27D0
Content-Type: text/plain;
charset="iso-2022-jp"
Content-Transfer-Encoding: 7bit
Hi all,
Could anyone help me with this problem?
I'm trying to call "generate" on a JETEmitter instance,
but a NullpointerEx gets thrown in JETEmitter.initialize().
This is my code:
JETEmitter emitter = new JETEmitter(
"/sandbox/templates/HelloWorld.javajet");
String[] args = new String[] {"hi" };
String result = emitter.generate(new NullProgressMonitor(), args);
System.out.println(result);
And this is the stack trace:
java.lang.NullPointerException
at org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:169)
at org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)
at runhello.Main.main(Main.java:24)
Exception in thread "main"
The line where the error occurs contains "CodeGenPlugin.getPlugin()", and I
think that this returns null, but I don't understand why. Is the plugin
not activated? I did create an interface with @model tags, generated a
genmodel, and generated an Edit and Editor project from that, so the plugin
should be activated...
Or am I missing something else completely?
Should I not use JETEmitter this way?
Any help would be very welcome.
Thanks,
Remko Popma
------=_NextPart_000_0036_01C31F79.5DDE27D0
Content-Type: image/gif;
name="jetsandbox.gif"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="jetsandbox.gif"
R0lGODlhtADLANUAAP//////zP//mf//Zv/Mmf/MZv/MM/+ZZv+ZM8zMzMzM mczMZszMM8yZZsyZ
M8xmZsxmM5nMzJnMmZmZmZmZZpmZM5mZAJlmmZlmZplmM5lmAJkzM2aZmWaZ ZmaZAGZmzGZmmWZm
ZmZmM2ZmAGYzzGYzZmYzMzOZzDOZmTNmzDNmmTNmZjMzzDMzmTMzZjMzMzMA mTMAZgCZmQAzZgAz
AAAA/wAAmQAAZgAAAP4BAgAAAAAAAAAAAAAAAAAAAAAAACH5BAUUADkALAAA AAC0AMsAAAb/wElI
OLl0LsShETlUHpPFZzPKJC6h12nWKuVWnV8qtgseh7dlLVmsPq/RgLg83pnb 7/h4Lc/v+/+AgYKD
hIWGhDaHiouMjY6GF4EjFpN3e4+YmZqbmCEEAgQLIXY3mTgAp5yqq4tQU3c4 OBYVFQsKtBoAiQCX
j6eprMHCf6N3xXM4KRUAAswABHpxu76ow9bXdhN42nfKzQKgAgUACTc1CXix wOpxv+vs6u+p69j1
i8dz+HLKzOEFDAb60EOGal61dgerDfxlr6EhbfFOadM2Sps3FxgzanQBTE7H grESMkRIb2BChygB
6YuzEoA3Ai5OcDhxIsXMFClApDNI0qPI/58mP6Ycuq1otwoCVtw8AQKnChWl 7JT0ObWn1YMjiWq1
07Klspg0U9RM8RRGHnbt4PkE6S5kWp4nt2p1RQRPihI1UXwgm1PFNLmAA/NZ YONG4cOGowpenJIb
48eQI0uebKyQY8qYM2veTOhyoJZ+THAefU1EBtMiTKA2IXqRUNLDQN+hO4RP BgIFChi4baCAg9aK
XsPe2pWPCAIGDDgIkdwBBeCHhA9f5ZmPY2DV5WRI3gCCCOUQfp91C9IjWrRs 35KUPp3RMWCyvzuo
AMGE8/DQ1yqkyt8qXHcItfdZIBDFA8BEAFQUB2sZhLCBCC6wVoIJOOQXV1UK GWggW1mxJ/+gIe/J
ER9yBjRgggDKPZeOVP3tR9CL+nn4YRzZGZVQjQBsZ0AFvynngHiwtNghUOcJ OWMneMSn3AO/OeeA
d+PJY55bRQZYZVxHVgYIbTia0MCTFZTwYwYmqoJeloGpxhqFa7KG5mM4WleI hW/Waed0svGR5518
9pllnHkAigedftaJ2mmqIUqoIDIO0iiMlO0pB5e24aYbb74tGsijZr5ZXB7H NcdcipoCwiknp85F
oH446tidfPhFOeWU85C3YZHkWVkQVuililmILBmnHH32URBrkFcNWdV/u55U 665DYhmZpDRyeOC1
CgLAoIMQSsgmsjESCc95GuqHla4Lear/34jcnUjqijAqyyKkP63FU7S+DiVo tQFem4eOPJrgI5Dz
umiwsldGq+u56aL5KR7yMVnskyLIqt5btTJbHlALG7ShtJBRe+AUr+ThJZhi OkBmqcHl2ki+fqrJ
WoVtYgYzYPtmM2ehPPf8mMj5+Cz00JzlPIfRcrBMNGmHpraa0gJZAxdnIlP6 r6W7IZcpIzebCq6d
D98RqnKjOgc1H13/IVTa+q7ab6vceQcewVLZajeVd2e8XrwbT10nsAkKO199 99EdLobynrt3vYo3
TvWqEV1Lkb/bPhihCRNW+DXH642Lt1r9Nuz43+saR6KJKJoN7+Et9us646L7 rVnO101q/1tyAQ9M
J+KcZ0ilkVZqzPZkYdsRcZMUUGzxxun1be/v/uH7umZVk1yXyV9CEOaYZaLq 8tLByMxmzeBjgzS/
g5xd/vrsCwK0iO3HL7/5lu08/3BNJ5ra7mpPfz/8W7Jeba6Wm6z1xnD+m9fw 5le8OYxtOc1R0ebg
tUA/0c5Gd3CV3J6EwAzNqmPf+x8xkiQ4YhVudx6zV7JEGLgtWQtB2apctzD3 rYK1BXoKY+EItQSx
07lLdeDKigpNcr8LzuZ2O+rRjzrIO4aZS4d9aKAcjjcxKAXxYoo70/2qRxc+ nEx7KVsZFCcjPpqt
aYyYOJ+/0ofGNsbvfcHqjBvrRJs5Yv/QbYOgVgegcTQ42hEbkcgGAWTTEeHI DnZ++EghAeNHLlqP
D3WQAwtYkIAQWPIs9FLhFRP4xApmRopxCGQcWKATclRsdSA7ZFASWTDBqNGI N4LkHCYZh0pi8nkN
69V+9OaijC3SecHzZD0AJxtRAoCW5ABNRKR3sJ4wpCRNfF0OQfaIRkLOQDBc YyTjAAIW1FKZBImc
E9G1y9bl0JfJ0uKvSpeHSLAgAsf0JgAC8IJbXmWI+HymORnXzF4+UROvxCN2 ZMmCFkwSBd+0Zz9T
GDpNGqyfK2woJ6dFwnaSIwUkaAE6kqlQXmYxV0GBXjBHgk7XfYwT1gxgF/Ow TTvY0mb//7uABBJA
0wREoKannIwwGxFQOf6hA5YMqlD9+MeiEiWleTTqjJZwhKYqFX2C6Kkf9miH CxD1qaswJo0EQMhM
LsyG/2wlrxSZEqT6wWp4aOkkK3lJVBrSf6uMWjjDmiVQAsCYpKxlTlv5VmnF FW0sImLbfPqH2kHV
DmqV50u/5tF72aqcznOsy36ZMCxKhph8wKtilRm5XNZLnwgDnjQD28lMmLUP BWJHNh3T0m4m1K3W
GqcT9XlPha0NY+kM4WIwa9F3xjMO9Owolhg622YuUnRzJSc/eVo/F76NoAZl AUI5ClvP/pVZx21d
chE5UUZWFA+RSABGNfpaxmJRsny7/xhlPRcSyRLxpI04rXUEiKOWzmGxnNnp aGRaU5vilDT6HYRU
NQHUoQoVqwhmjHwTzOCeDTgQ6mswK/L3NK71j5qFciQUKlVATHXQURcOsMO+ KzYSQfBdrglx+WB5
NCS+am78k9fv7qZJdb6RxMYbFuGMxUTseoy491pun6r2QmxRzgQNspy3NAfW FUKzStO8MQ9L3K7U
SbDJxtWubEUMJzy2+F+4U+KP+Be83jEzyu2zKxWdZEW+0nahjx2r0DRcskFl b3sq656E7VHGNkX4
qQ8GxJ/3TGjiFMKPavQDAXCw6EYz+tGOjjSkJy3pSlOa0XOsYzpmwOlOe/rT oA61qP9H7Wkup7G5
Sf0pHyfVEgLM4AachvWrY03rWdta1riuda5vXetVo1GrBxokLDgNgBu44NUu AACnYxDrYyvbBbJm
NrKVbexOS7vayLb2DExdzUMTiL6ylCQlg2oHAcA6DrJGd607vWtZ21rX7Pa0 u309ZxzPAa+lTMBe
UTGDGMSh3zP497EBnu2CE5zg2D74tQd+AxpMJtCBYlW4R7lZO7g64BhXdrED /u9zZ3zjs1Y2xzdO
bYyPXNb09hlvwTvLiiOD2BnHuLufrXGRi7zf1B64xpedc5jfgNuOWHBRIrda ObTW5XIwd8x3PnKS
y/zpAT+3HDxe8jlwOuU9W/kd3An/T2QG9+X+frXNSxFysWMc2s+meqypvfNk r/3VDpcMxG00UJYe
M7rTxe8zYB71jKcb5iAHecw97vOnixzrPLNreMe7Ub3jgNjYDnvTcW5ysis7 7Iq5vMmJPfVtE8/b
Kn2k3fGgd1e7u93x5nW8Bb/ua68b8SLkb01vStN9Px7anMY9wge++2af3ffL Bv4MdA905hKWwAY+
8ByUDm/V7/rdz1d96q9eaFRY+vqMpkGjtX9p7Fv684S4avXH/3BUC6KU5K/H BNbP/vajfxPF/+S3
V7qNANg/ABO4fwDe71VC9JWFdpV/tgNc/EdXIIZKDuZlA1h/C7h/O9FY0IJb waRe/zQGPgEYAHJA
CQR4SwsBIMxUY6J1JERGdEbGDe0nBKAwBOtXgGOFQxFVUr50SPU2ZdmAgRYA DgSQg+DQErITZOni
WbAQf/bAYgs4Gxg4AuGAgwRgARQEggv1WQ0lWCpnb5NigzkoAh6gAZRgATx4 XuiiS80jZ5YlgvMn
evUXABZAAAzAAAiwhsvhCEI4PxMAAiBgASKwRD+yAtQARXPXByyYfoCoFUKH WoEYGZqmVH2oJ4BA
VX1UiMIAbCHAVYBFV6oULnJlLjCjX4MoJz8FADLAARwAT1bVVubVhJuEYRfC CnGYVXmgd5jIgasj
hWLFZV2TiHmgR54IiqAIT65oUv9eKIblxEskJYET+FlxRi6ryAnAVl51Uy4d A4WgRRXRlIqCBWTd
5QebGHGTs41Gl4u6yIvgJI1QBo2Q9VDnJIEdgiu3IiDLOE/1VF3IIj3RWFv8 JI8SJUTXSIjHNyCd
+InfSF3mZV2W2DhCdI7XhU9fNRzt2IvO8oseBTsi1YIfFWfoaFk3k413NHp3 wJCMkYl3Inv9VXsw
ZQgBZotUeAcFlnzi54gsCUCpJmAtuRhMxVRYZZI0yFL0ZlUxqQrAtkddRYlw NZAKBYz5iICHgJFH
1I+7eFfkBlumiGUeQlayiAnJ6AgLGY4JVIkSNYkhCH8wuY8qsYjeuJQMuV65 9Fj/tIUrI8VX6oVL
bsk8mXGVUQI6WUSObwYgETVa20VWT+g+oAeT3JgtAFAH/kiWWOk7LviD5ViQ 3PUi6ygPP3YlmtGO
XxeQ8WiXWQY8r2GP5ChWZ2V+mUCYuhiKAMmWArmV2LWXqdSYipmQcdmKhwmB RBlSU4NOnbWWJgVl
IOWX4acK9iUHHKlT0XEkIBmS+5YZHukINmkIKZl8O/mcL8mb0AkYKpMBDrCT yxkH1nkAxzlHNmYP
KnOdOTImFLAAm4IxkLk23+mV20WVFCQcdHY9diBGOdIACJABA5AB59mQ1PRL FzacE/QyKzI8UpQB
EJABT/EjB1ABBVABG8VK/CkdnPnSNZvJnqTFiYUlcRnkACXAASqQAQgwHw3Q oF4ToZd4j5/jhe2F
gDcUPSkkhRWKimHZLy2RAQ9gAiigAhhAniQaYh8DXx/URMLjgZsTWoGlMV41 lSOITSU4niagAigA
og2QAQzqoCq2lRA6TTH4jLPYO+mRXQFaQVqnHd5BFtaJACKQACO6DLHoi/3p mM6CXFxKL4njpfiI
mgcRBAA7
------=_NextPart_000_0036_01C31F79.5DDE27D0--
|
|
|
| Re: getting started with JETEmitter [message #377598 is a reply to message #377594] |
Wed, 21 May 2003 07:37   |
Ed Merks Messages: 24564 Registered: July 2009 |
Senior Member |
|
|
Remko,
JET is designed to run only as a workspace application so you must mimimally
run it as an Eclipse headless application (so that plugin initialization takes
places).
Remko Popma wrote:
> Hi all,
>
> Could anyone help me with this problem?
>
> I'm trying to call "generate" on a JETEmitter instance,
> but a NullpointerEx gets thrown in JETEmitter.initialize().
>
> This is my code:
>
> JETEmitter emitter = new JETEmitter(
> "/sandbox/templates/HelloWorld.javajet");
> String[] args = new String[] {"hi" };
> String result = emitter.generate(new NullProgressMonitor(), args);
> System.out.println(result);
>
> And this is the stack trace:
>
> java.lang.NullPointerException
> at org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:169)
> at org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)
> at runhello.Main.main(Main.java:24)
> Exception in thread "main"
>
> The line where the error occurs contains "CodeGenPlugin.getPlugin()", and I
> think that this returns null, but I don't understand why. Is the plugin
> not activated? I did create an interface with @model tags, generated a
> genmodel, and generated an Edit and Editor project from that, so the plugin
> should be activated...
> Or am I missing something else completely?
> Should I not use JETEmitter this way?
>
> Any help would be very welcome.
> Thanks,
> Remko Popma
>
> ------------------------------------------------------------ ------------
> Name: jetsandbox.gif
> jetsandbox.gif Type: GIF Image (image/gif)
> Encoding: base64
|
|
|
| Re: getting started with JETEmitter [message #377617 is a reply to message #377598] |
Thu, 22 May 2003 20:55   |
|
Originally posted by: remko.popma.azzurri.jp
Ed,
Thanks for your reply. Calling JETEmitter from a plugin action (like
org.eclipse.emf.codegen.action.CompileTemplateAction) solved
the NullPointerException problem.
I'm not sure if it's ok to ask a new question in the same thread, but here
goes:
From a previous post
( http://www.eclipse.org/newsportal/article.php3?id=58&gro up=eclipse.tools.em
f) I understood that it's possible to pass
my custom model (that is, a non-ecore model) to a template. So instead of
passing a String argument, I now try to pass a simple bean class (extending
Object) to the template.
This looks like it should work, but a NoClassDefFoundError gets thrown
when JETEmitter.generate() is called.
This is where I got stuck... I've added my bean class to the classpath
of the .JETEmitters project in several different ways, but it doesn't seem
to make a difference.
More details follow below.
Any pointers would be greatly appreciated.
The template looks like this:
<%@ jet package="hello" imports="main.*" class="HelloWorld" %>
<% Employee employee = (Employee)argument; %>
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Employee name=<%= employee.getName() %>");
}
}
And the action that calls it looks like this:
JETEmitter emit = new JETEmitter(templateURI);
Employee employee = new Employee();
String result = emit.generate(new NullProgressMonitor(), new Object[]
{employee});
System.out.println(result);
The first time I got this exception:
org.eclipse.emf.codegen.jet.JETException: Resource /.JETEmitters/runtime
already exists.
at org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:383)
at org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)
at main.Main.run(Main.java:51)
This happened only once.
Next, nothing happened when I ran my action, until I figured out that the
javajet
template was compiled into a HelloWorld.java source file correctly, but the
source file could not compile. The HelloWorld.java source file is located in
a
project called .JETEmitters that gets created by JETEmitter. Adding
Employee to the classpath of the .JETEmitters project solved
the compilation problem.
Running my emit action again got the exception below,
where the cause seems to be a NoClassDefFoundError.
---------------------
org.eclipse.emf.codegen.jet.JETException[0]:
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.java:39
)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorImpl
..java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:429)
at main.Main.run(Main.java:51)
at org.eclipse.ui.internal.PluginAction.runWithEvent(PluginActi on.java:251)
at
org.eclipse.jface.action.ActionContributionItem.handleWidget Selection(Action
ContributionItem.java:456)
at
org.eclipse.jface.action.ActionContributionItem.handleWidget Event(ActionCont
ributionItem.java:403)
at
org.eclipse.jface.action.ActionContributionItem.access$0(Act ionContributionI
tem.java:397)
at
org.eclipse.jface.action.ActionContributionItem$ActionListen er.handleEvent(A
ctionContributionItem.java:72)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java :81)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:840)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.ja va:1838)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :1545)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:1402)
at org.eclipse.ui.internal.Workbench.run(Workbench.java:1385)
at
org.eclipse.core.internal.boot.InternalBootLoader.run(Intern alBootLoader.jav
a:845)
at org.eclipse.core.boot.BootLoader.run(BootLoader.java:461)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.java:39
)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorImpl
..java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.eclipse.core.launcher.Main.basicRun(Main.java:291)
at org.eclipse.core.launcher.Main.run(Main.java:747)
at org.eclipse.core.launcher.Main.main(Main.java:583)
Caused by: java.lang.NoClassDefFoundError: main/Employee
at hello.HelloWorld.generate(HelloWorld.java:22)
... 26 more
Unhandled exception caught in event loop.
Reason:
org.eclipse.emf.codegen.jet.JETException:
--------------------------
I've tried to change the way the Employee class is added to the classpath,
but nothing seems to make a difference. Any help would be very welcome.
Thanks,
Remko Popma
"Ed Merks" <merks@ca.ibm.com> wrote in message
news:3ECB64E5.A16E8DCD@ca.ibm.com...
> Remko,
>
> JET is designed to run only as a workspace application so you must
mimimally
> run it as an Eclipse headless application (so that plugin initialization
takes
> places).
>
>
> Remko Popma wrote:
>
> > Hi all,
> >
> > Could anyone help me with this problem?
> >
> > I'm trying to call "generate" on a JETEmitter instance,
> > but a NullpointerEx gets thrown in JETEmitter.initialize().
> >
> > This is my code:
> >
> > JETEmitter emitter = new JETEmitter(
> > "/sandbox/templates/HelloWorld.javajet");
> > String[] args = new String[] {"hi" };
> > String result = emitter.generate(new NullProgressMonitor(), args);
> > System.out.println(result);
> >
> > And this is the stack trace:
> >
> > java.lang.NullPointerException
> > at
org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:169)
> > at org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)
> > at runhello.Main.main(Main.java:24)
> > Exception in thread "main"
> >
> > The line where the error occurs contains "CodeGenPlugin.getPlugin()",
and I
> > think that this returns null, but I don't understand why. Is the plugin
> > not activated? I did create an interface with @model tags, generated a
> > genmodel, and generated an Edit and Editor project from that, so the
plugin
> > should be activated...
> > Or am I missing something else completely?
> > Should I not use JETEmitter this way?
> >
> > Any help would be very welcome.
> > Thanks,
> > Remko Popma
> >
>
------------------------------------------------------------ ------------
> > Name: jetsandbox.gif
> > jetsandbox.gif Type: GIF Image (image/gif)
> > Encoding: base64
>
|
|
|
| Re: getting started with JETEmitter [message #377619 is a reply to message #377617] |
Fri, 23 May 2003 06:47   |
Ed Merks Messages: 24564 Registered: July 2009 |
Senior Member |
|
|
--------------0DD6D182C6272B20FB3851E2
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Remko,
In the JETEmitter there is this line of code:
URLClassLoader classLoader = new URLClassLoader(new URL [] { url },
JETEmitter.this.getClass().getClassLoader());
Notice that it's using the class loader of the JETEmitter class itself.
Everywhere that we use the JETEmitter in the GenModel code we use it like this:
interfaceEmitter = new JETEmitter(getTemplatePath(),
interfaceTemplateName) {};
Notice that it uses an inner class and therefore the code above will pick up the
class loader that can load GenModel classes. Without the inner classes, the
classloader of the JETEmitter itself, i.e., the classloader for the
org.eclipse.emf.codegen plugin, and it can't see much.
Clearly this is very non-obvious, and there isn't even a speck of Javadoc. I'm
going to change the JETEmitter code so that the class loader can be provided as
an argument and I'm going to change the GenModel to use it like this:
interfaceEmitter = new JETEmitter(getTemplatePath(),
interfaceTemplateName, getClass().getClassLoader());
I think this will make the behavior more obvious. Sorry you had to struggle so
hard...
Remko Popma wrote:
> Ed,
>
> Thanks for your reply. Calling JETEmitter from a plugin action (like
> org.eclipse.emf.codegen.action.CompileTemplateAction) solved
> the NullPointerException problem.
>
> I'm not sure if it's ok to ask a new question in the same thread, but here
> goes:
>
> From a previous post
> ( http://www.eclipse.org/newsportal/article.php3?id=58&gro up=eclipse.tools.em
> f) I understood that it's possible to pass
> my custom model (that is, a non-ecore model) to a template. So instead of
> passing a String argument, I now try to pass a simple bean class (extending
> Object) to the template.
>
> This looks like it should work, but a NoClassDefFoundError gets thrown
> when JETEmitter.generate() is called.
> This is where I got stuck... I've added my bean class to the classpath
> of the .JETEmitters project in several different ways, but it doesn't seem
> to make a difference.
>
> More details follow below.
> Any pointers would be greatly appreciated.
>
> The template looks like this:
> <%@ jet package="hello" imports="main.*" class="HelloWorld" %>
> <% Employee employee = (Employee)argument; %>
> public class HelloWorld {
> public static void main(String[] args) {
> System.out.println("Employee name=<%= employee.getName() %>");
> }
> }
>
> And the action that calls it looks like this:
> JETEmitter emit = new JETEmitter(templateURI);
> Employee employee = new Employee();
> String result = emit.generate(new NullProgressMonitor(), new Object[]
> {employee});
> System.out.println(result);
>
> The first time I got this exception:
> org.eclipse.emf.codegen.jet.JETException: Resource /.JETEmitters/runtime
> already exists.
> at org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:383)
> at org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)
> at main.Main.run(Main.java:51)
>
> This happened only once.
> Next, nothing happened when I ran my action, until I figured out that the
> javajet
> template was compiled into a HelloWorld.java source file correctly, but the
> source file could not compile. The HelloWorld.java source file is located in
> a
> project called .JETEmitters that gets created by JETEmitter. Adding
> Employee to the classpath of the .JETEmitters project solved
> the compilation problem.
>
> Running my emit action again got the exception below,
> where the cause seems to be a NoClassDefFoundError.
> ---------------------
> org.eclipse.emf.codegen.jet.JETException[0]:
> java.lang.reflect.InvocationTargetException
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.java:39
> )
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorImpl
> .java:25)
> at java.lang.reflect.Method.invoke(Method.java:324)
> at org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:429)
> at main.Main.run(Main.java:51)
> at org.eclipse.ui.internal.PluginAction.runWithEvent(PluginActi on.java:251)
> at
> org.eclipse.jface.action.ActionContributionItem.handleWidget Selection(Action
> ContributionItem.java:456)
> at
> org.eclipse.jface.action.ActionContributionItem.handleWidget Event(ActionCont
> ributionItem.java:403)
> at
> org.eclipse.jface.action.ActionContributionItem.access$0(Act ionContributionI
> tem.java:397)
> at
> org.eclipse.jface.action.ActionContributionItem$ActionListen er.handleEvent(A
> ctionContributionItem.java:72)
> at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java :81)
> at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:840)
> at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.ja va:1838)
> at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :1545)
> at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:1402)
> at org.eclipse.ui.internal.Workbench.run(Workbench.java:1385)
> at
> org.eclipse.core.internal.boot.InternalBootLoader.run(Intern alBootLoader.jav
> a:845)
> at org.eclipse.core.boot.BootLoader.run(BootLoader.java:461)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.java:39
> )
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorImpl
> .java:25)
> at java.lang.reflect.Method.invoke(Method.java:324)
> at org.eclipse.core.launcher.Main.basicRun(Main.java:291)
> at org.eclipse.core.launcher.Main.run(Main.java:747)
> at org.eclipse.core.launcher.Main.main(Main.java:583)
> Caused by: java.lang.NoClassDefFoundError: main/Employee
> at hello.HelloWorld.generate(HelloWorld.java:22)
> ... 26 more
> Unhandled exception caught in event loop.
> Reason:
> org.eclipse.emf.codegen.jet.JETException:
> --------------------------
>
> I've tried to change the way the Employee class is added to the classpath,
> but nothing seems to make a difference. Any help would be very welcome.
>
> Thanks,
>
> Remko Popma
>
> "Ed Merks" <merks@ca.ibm.com> wrote in message
> news:3ECB64E5.A16E8DCD@ca.ibm.com...
> > Remko,
> >
> > JET is designed to run only as a workspace application so you must
> mimimally
> > run it as an Eclipse headless application (so that plugin initialization
> takes
> > places).
> >
> >
> > Remko Popma wrote:
> >
> > > Hi all,
> > >
> > > Could anyone help me with this problem?
> > >
> > > I'm trying to call "generate" on a JETEmitter instance,
> > > but a NullpointerEx gets thrown in JETEmitter.initialize().
> > >
> > > This is my code:
> > >
> > > JETEmitter emitter = new JETEmitter(
> > > "/sandbox/templates/HelloWorld.javajet");
> > > String[] args = new String[] {"hi" };
> > > String result = emitter.generate(new NullProgressMonitor(), args);
> > > System.out.println(result);
> > >
> > > And this is the stack trace:
> > >
> > > java.lang.NullPointerException
> > > at
> org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:169)
> > > at org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)
> > > at runhello.Main.main(Main.java:24)
> > > Exception in thread "main"
> > >
> > > The line where the error occurs contains "CodeGenPlugin.getPlugin()",
> and I
> > > think that this returns null, but I don't understand why. Is the plugin
> > > not activated? I did create an interface with @model tags, generated a
> > > genmodel, and generated an Edit and Editor project from that, so the
> plugin
> > > should be activated...
> > > Or am I missing something else completely?
> > > Should I not use JETEmitter this way?
> > >
> > > Any help would be very welcome.
> > > Thanks,
> > > Remko Popma
> > >
> >
> ------------------------------------------------------------ ------------
> > > Name: jetsandbox.gif
> > > jetsandbox.gif Type: GIF Image (image/gif)
> > > Encoding: base64
> >
--------------0DD6D182C6272B20FB3851E2
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
Remko,
<p>In the JETEmitter there is this line of code:
<blockquote>URLClassLoader classLoader = new URLClassLoader(new URL []
{ url }, JETEmitter.this.getClass().getClassLoader());</blockquote>
Notice that it's using the class loader of the JETEmitter class itself.
Everywhere that we use the JETEmitter in the GenModel code we use it like
this:
<blockquote> interfaceEmitter = new JETEmitter(getTemplatePath(),
interfaceTemplateName) {};</blockquote>
Notice that it uses an inner class and therefore the code above will pick
up the class loader that can load GenModel classes. Without the inner
classes, the classloader of the JETEmitter itself, i.e., the classloader
for the org.eclipse.emf.codegen plugin, and it can't see much.
<p>Clearly this is very non-obvious, and there isn't even a speck of Javadoc.
I'm going to change the JETEmitter code so that the class loader can be
provided as an argument and I'm going to change the GenModel to use it
like this:
<blockquote>interfaceEmitter = new JETEmitter(getTemplatePath(), interfaceTemplateName,
getClass().getClassLoader());</blockquote>
I think this will make the behavior more obvious. Sorry you had to
struggle so hard...
<br>
<p>Remko Popma wrote:
<blockquote TYPE=CITE>Ed,
<p>Thanks for your reply. Calling JETEmitter from a plugin action (like
<br>org.eclipse.emf.codegen.action.CompileTemplateAction) solved
<br>the NullPointerException problem.
<p>I'm not sure if it's ok to ask a new question in the same thread, but
here
<br>goes:
<p>From a previous post
<br>(<a href=" http://www.eclipse.org/newsportal/article.php3?id=58&gro up=eclipse.tools.em"> http://www.eclipse.org/newsportal/article.php3?id=58&group=eclipse.tools.em</a>
<br>f) I understood that it's possible to pass
<br>my custom model (that is, a non-ecore model) to a template. So instead
of
<br>passing a String argument, I now try to pass a simple bean class (extending
<br>Object) to the template.
<p>This looks like it should work, but a NoClassDefFoundError gets thrown
<br>when JETEmitter.generate() is called.
<br>This is where I got stuck... I've added my bean class to the classpath
<br>of the .JETEmitters project in several different ways, but it doesn't
seem
<br>to make a difference.
<p>More details follow below.
<br>Any pointers would be greatly appreciated.
<p>The template looks like this:
<br><%@ jet package="hello" imports="main.*" class="HelloWorld" %>
<br><% Employee employee = (Employee)argument; %>
<br>public class HelloWorld {
<br> public static void main(String[] args) {
<br> System.out.println("Employee name=<%= employee.getName()
%>");
<br> }
<br>}
<p>And the action that calls it looks like this:
<br>JETEmitter emit = new JETEmitter(templateURI);
<br>Employee employee = new Employee();
<br>String result = emit.generate(new NullProgressMonitor(), new Object[]
<br>{employee});
<br>System.out.println(result);
<p>The first time I got this exception:
<br>org.eclipse.emf.codegen.jet.JETException: Resource /.JETEmitters/runtime
<br>already exists.
<br> at org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:383)
<br> at org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)
<br> at main.Main.run(Main.java:51)
<p>This happened only once.
<br>Next, nothing happened when I ran my action, until I figured out that
the
<br>javajet
<br>template was compiled into a HelloWorld.java source file correctly,
but the
<br>source file could not compile. The HelloWorld.java source file is located
in
<br>a
<br>project called .JETEmitters that gets created by JETEmitter. Adding
<br>Employee to the classpath of the .JETEmitters project solved
<br>the compilation problem.
<p>Running my emit action again got the exception below,
<br>where the cause seems to be a NoClassDefFoundError.
<br>---------------------
<br>org.eclipse.emf.codegen.jet.JETException[0]:
<br>java.lang.reflect.InvocationTargetException
<br> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
<br> at
<br> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.java:39
<br>)
<br> at
<br> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorImpl
<br>.java:25)
<br> at java.lang.reflect.Method.invoke(Method.java:324)
<br> at org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:429)
<br> at main.Main.run(Main.java:51)
<br> at org.eclipse.ui.internal.PluginAction.runWithEvent(PluginActi on.java:251)
<br> at
<br> org.eclipse.jface.action.ActionContributionItem.handleWidget Selection(Action
<br>ContributionItem.java:456)
<br> at
<br> org.eclipse.jface.action.ActionContributionItem.handleWidget Event(ActionCont
<br>ributionItem.java:403)
<br> at
<br> org.eclipse.jface.action.ActionContributionItem.access$0(Act ionContributionI
<br>tem.java:397)
<br> at
<br> org.eclipse.jface.action.ActionContributionItem$ActionListen er.handleEvent(A
<br>ctionContributionItem.java:72)
<br> at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java :81)
<br> at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:840)
<br> at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.ja va:1838)
<br> at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :1545)
<br> at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:1402)
<br> at org.eclipse.ui.internal.Workbench.run(Workbench.java:1385)
<br> at
<br> org.eclipse.core.internal.boot.InternalBootLoader.run(Intern alBootLoader.jav
<br>a:845)
<br> at org.eclipse.core.boot.BootLoader.run(BootLoader.java:461)
<br> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
<br> at
<br> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.java:39
<br>)
<br> at
<br> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorImpl
<br>.java:25)
<br> at java.lang.reflect.Method.invoke(Method.java:324)
<br> at org.eclipse.core.launcher.Main.basicRun(Main.java:291)
<br> at org.eclipse.core.launcher.Main.run(Main.java:747)
<br> at org.eclipse.core.launcher.Main.main(Main.java:583)
<br>Caused by: java.lang.NoClassDefFoundError: main/Employee
<br> at hello.HelloWorld.generate(HelloWorld.java:22)
<br> ... 26 more
<br>Unhandled exception caught in event loop.
<br>Reason:
<br>org.eclipse.emf.codegen.jet.JETException:
<br>--------------------------
<p>I've tried to change the way the Employee class is added to the classpath,
<br>but nothing seems to make a difference. Any help would be very welcome.
<p>Thanks,
<p>Remko Popma
<p>"Ed Merks" <merks@ca.ibm.com> wrote in message
<br><a href="news:3ECB64E5.A16E8DCD@ca.ibm.com">news:3ECB64E5.A16E8DCD@ca.ibm.com</a>...
<br>> Remko,
<br>>
<br>> JET is designed to run only as a workspace application so you must
<br>mimimally
<br>> run it as an Eclipse headless application (so that plugin initialization
<br>takes
<br>> places).
<br>>
<br>>
<br>> Remko Popma wrote:
<br>>
<br>> > Hi all,
<br>> >
<br>> > Could anyone help me with this problem?
<br>> >
<br>> > I'm trying to call "generate" on a JETEmitter instance,
<br>> > but a NullpointerEx gets thrown in JETEmitter.initialize().
<br>> >
<br>> > This is my code:
<br>> >
<br>> > JETEmitter emitter = new JETEmitter(
<br>> > "/sandbox/templates/HelloWorld.javajet");
<br>> > String[] args = new String[] {"hi" };
<br>> > String result = emitter.generate(new NullProgressMonitor(), args);
<br>> > System.out.println(result);
<br>> >
<br>> > And this is the stack trace:
<br>> >
<br>> > java.lang.NullPointerException
<br>> > at
<br> org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:169)
<br>> > at org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)
<br>> > at runhello.Main.main(Main.java:24)
<br>> > Exception in thread "main"
<br>> >
<br>> > The line where the error occurs contains "CodeGenPlugin.getPlugin()",
<br>and I
<br>> > think that this returns null, but I don't understand why. Is the
plugin
<br>> > not activated? I did create an interface with @model tags, generated
a
<br>> > genmodel, and generated an Edit and Editor project from that, so
the
<br>plugin
<br>> > should be activated...
<br>> > Or am I missing something else completely?
<br>> > Should I not use JETEmitter this way?
<br>> >
<br>> > Any help would be very welcome.
<br>> > Thanks,
<br>> > Remko Popma
<br>> >
<br>>
<br> ------------------------------------------------------------ ------------
<br>> >
Name: jetsandbox.gif
<br>> > jetsandbox.gif Type: GIF Image
(image/gif)
<br>> >
Encoding: base64
<br>></blockquote>
</html>
--------------0DD6D182C6272B20FB3851E2--
|
|
|
| Re: getting started with JETEmitter [message #377621 is a reply to message #377619] |
Fri, 23 May 2003 13:07   |
|
Originally posted by: remko.popma.azzurri.jp
This is a multi-part message in MIME format.
------=_NextPart_000_00F6_01C32199.3622A960
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Ed,
Thanks!
Interesting hack with the inner class. I didn't notice the brackets in the
GenModel code...
An extra constructor that takes a classloader would be good, I agree.
If you are going to change JETEmitter, can I make a request?
Could you add some API to make it possible to add IClasspathEntries to the
emitter before initialize is called?
Currently all classpath entries are hard-coded (JRELIB, EMF_COMMON,
EMF_ECORE, EMF_CODEGEN, and EMF_CODEGEN_ECORE),
which kind of assumes that the meta model is a genModel.
I would like to use my own meta model but there is no clean way to add my
classes to the classpath now.
An addClasspathEntry method would be great.
(Come to think of it, perhaps the EMF classpaths don't really belong in the
jet package. If JETEmitter has a method
to add IClasspathEntries, it might make sense to have a subclass of
JETEmitter (GenModelEmitter or something, you can probably
think of a better name) in the org.eclipse.emf.codegen.ecore.genmodel
package that would add all the classpath
entries needed for EMF code generation. Or have a factory method for
creating a JETEmitter instance
(instead of calling "new JETEmitter(getTemplatePath(), templateName) { }")
that creates the instance and adds the necessary classpath entries.
This would remove the last genmodel dependency from the jet package...
Hm... Might be a lot of work in the genmodel package. Oh well. Just my 2
cents.)
Thanks again for the help.
Remko
"Ed Merks" <merks@ca.ibm.com> wrote in message
news:3ECDFC5E.B7E5E4F4@ca.ibm.com...
Remko,
In the JETEmitter there is this line of code:
URLClassLoader classLoader = new URLClassLoader(new URL [] { url },
JETEmitter.this.getClass().getClassLoader());
Notice that it's using the class loader of the JETEmitter class itself.
Everywhere that we use the JETEmitter in the GenModel code we use it like
this:
interfaceEmitter = new JETEmitter(getTemplatePath(),
interfaceTemplateName) {};
Notice that it uses an inner class and therefore the code above will pick
up the class loader that can load GenModel classes. Without the inner
classes, the classloader of the JETEmitter itself, i.e., the classloader for
the org.eclipse.emf.codegen plugin, and it can't see much.
Clearly this is very non-obvious, and there isn't even a speck of Javadoc.
I'm going to change the JETEmitter code so that the class loader can be
provided as an argument and I'm going to change the GenModel to use it like
this:
interfaceEmitter = new JETEmitter(getTemplatePath(),
interfaceTemplateName, getClass().getClassLoader());
I think this will make the behavior more obvious. Sorry you had to
struggle so hard...
Remko Popma wrote:
Ed,
Thanks for your reply. Calling JETEmitter from a plugin action (like
org.eclipse.emf.codegen.action.CompileTemplateAction) solved
the NullPointerException problem.
I'm not sure if it's ok to ask a new question in the same thread, but
here
goes:
From a previous post
( http://www.eclipse.org/newsportal/article.php3?id=58&gro up=eclipse.tools.em
f) I understood that it's possible to pass
my custom model (that is, a non-ecore model) to a template. So instead
of
passing a String argument, I now try to pass a simple bean class
(extending
Object) to the template.
This looks like it should work, but a NoClassDefFoundError gets thrown
when JETEmitter.generate() is called.
This is where I got stuck... I've added my bean class to the classpath
of the .JETEmitters project in several different ways, but it doesn't
seem
to make a difference.
More details follow below.
Any pointers would be greatly appreciated.
The template looks like this:
<%@ jet package="hello" imports="main.*" class="HelloWorld" %>
<% Employee employee = (Employee)argument; %>
public class HelloWorld
public static void main(String[] args)
System.out.println("Employee name=<%= employee.getName() %>");
}
}
And the action that calls it looks like this:
JETEmitter emit = new JETEmitter(templateURI);
Employee employee = new Employee();
String result = emit.generate(new NullProgressMonitor(), new Object[]
{employee});
System.out.println(result);
The first time I got this exception:
org.eclipse.emf.codegen.jet.JETException: Resource /.JETEmitters/runtime
already exists.
at
org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:383)
at org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)
at main.Main.run(Main.java:51)
This happened only once.
Next, nothing happened when I ran my action, until I figured out that
the
javajet
template was compiled into a HelloWorld.java source file correctly, but
the
source file could not compile. The HelloWorld.java source file is
located in
a
project called .JETEmitters that gets created by JETEmitter. Adding
Employee to the classpath of the .JETEmitters project solved
the compilation problem.
Running my emit action again got the exception below,
where the cause seems to be a NoClassDefFoundError.
---------------------
org.eclipse.emf.codegen.jet.JETException[0]:
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.java:39
)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorImpl
.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:429)
at main.Main.run(Main.java:51)
at
org.eclipse.ui.internal.PluginAction.runWithEvent(PluginActi on.java:251)
at
org.eclipse.jface.action.ActionContributionItem.handleWidget Selection(Action
ContributionItem.java:456)
at
org.eclipse.jface.action.ActionContributionItem.handleWidget Event(ActionCont
ributionItem.java:403)
at
org.eclipse.jface.action.ActionContributionItem.access$0(Act ionContributionI
tem.java:397)
at
org.eclipse.jface.action.ActionContributionItem$ActionListen er.handleEvent(A
ctionContributionItem.java:72)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java :81)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:840)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.ja va:1838)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :1545)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:1402)
at org.eclipse.ui.internal.Workbench.run(Workbench.java:1385)
at
org.eclipse.core.internal.boot.InternalBootLoader.run(Intern alBootLoader.jav
a:845)
at org.eclipse.core.boot.BootLoader.run(BootLoader.java:461)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.java:39
)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorImpl
.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.eclipse.core.launcher.Main.basicRun(Main.java:291)
at org.eclipse.core.launcher.Main.run(Main.java:747)
at org.eclipse.core.launcher.Main.main(Main.java:583)
Caused by: java.lang.NoClassDefFoundError: main/Employee
at hello.HelloWorld.generate(HelloWorld.java:22)
... 26 more
Unhandled exception caught in event loop.
Reason:
org.eclipse.emf.codegen.jet.JETException:
--------------------------
I've tried to change the way the Employee class is added to the
classpath,
but nothing seems to make a difference. Any help would be very welcome.
Thanks,
Remko Popma
"Ed Merks" <merks@ca.ibm.com> wrote in message
news:3ECB64E5.A16E8DCD@ca.ibm.com...
> Remko,
>
> JET is designed to run only as a workspace application so you must
mimimally
> run it as an Eclipse headless application (so that plugin
initialization
takes
> places).
>
>
> Remko Popma wrote:
>
> > Hi all,
> >
> > Could anyone help me with this problem?
> >
> > I'm trying to call "generate" on a JETEmitter instance,
> > but a NullpointerEx gets thrown in JETEmitter.initialize().
> >
> > This is my code:
> >
> > JETEmitter emitter = new
Emitter(
> > "/sandbox/templates/HelloWorld.javajet");
> > String[] args = new String[] {"hi" };
> > String result = emitter.generate(new NullProgressMonitor(), args);
> > System.out.println(result);
> >
> > And this is the stack trace:
> >
> > java.lang.NullPointerException
> > at
org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:169)
> > at org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)
> > at runhello.Main.main(Main.java:24)
> > Exception in thread "main"
> >
> > The line where the error occurs contains "CodeGenPlugin.getPlugin()",
and I
> > think that this returns null, but I don't understand why. Is the plugin
> > not activated? I did create an interface with @model tags, generated a
> > genmodel, and generated an Edit and Editor project from that, so the
plugin
> > should be activated...
> > Or am I missing something else completely?
> > Should I not use JETEmitter this way?
> >
> > Any help would be very welcome.
> > Thanks,
> > Remko Popma
> >
>
------------------------------------------------------------ ------------
> > Name: jetsandbox.gif
> > jetsandbox.gif Type: GIF Image (image/gif)
> > Encoding: base64
>
------=_NextPart_000_00F6_01C32199.3622A960
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content=3D"text/html; charset=3Diso-8859-1" =
http-equiv=3DContent-Type>
<META content=3D"MSHTML 5.00.2920.0" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Ed,</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Thanks!</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Interesting hack with =
the inner class. I=20
didn't notice the brackets in the GenModel code...</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>An extra constructor =
that takes a classloader=20
would be good, I agree.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>If you are going to =
change JETEmitter, can I=20
make a request?</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Could you add some =
API to make it possible to=20
add IClasspathEntries to the emitter before initialize is =
called?</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Currently all =
classpath entries are hard-coded=20
(JRELIB, EMF_COMMON, EMF_ECORE, EMF_CODEGEN, and=20
EMF_CODEGEN_ECORE),</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>which kind of assumes =
that the meta model is a=20
genModel. </FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>I would like to use =
my own meta model but=20
there is no clean way to add my classes to the classpath =
now.</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>An addClasspathEntry =
method would be=20
great.</FONT></DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>(Come to think of it, =
perhaps the EMF=20
classpaths don't really belong in the jet package. If JETEmitter has a=20
method</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>to add =
IClasspathEntries, it might make sense=20
to have a subclass of JETEmitter (GenModelEmitter or something, you can=20
probably</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>think of a better =
name) in the=20
org.eclipse.emf.codegen.ecore.genmodel package that would add all the=20
classpath</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>entries needed for =
EMF code generation. Or=20
have a factory method for creating a JETEmitter =
instance</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>(instead of calling =
"new=20
JETEmitter(getTemplatePath(), templateName) { }") that creates the =
instance and=20
adds the necessary classpath entries.</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>This would remove the =
last genmodel=20
dependency from the jet package...</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Hm... Might be a lot =
of work in the genmodel=20
package. Oh well. Just my 2 cents.)</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Thanks again for the =
help.</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Remko</FONT></DIV>
<DIV> </DIV>
<BLOCKQUOTE=20
style=3D"BORDER-LEFT: #000000 2px solid; MARGIN-LEFT: 5px; MARGIN-RIGHT: =
0px; PADDING-LEFT: 5px; PADDING-RIGHT: 0px">
<DIV>"Ed Merks" <<A =
href=3D"mailto:merks@ca.ibm.com">merks@ca.ibm.com</A>>=20
wrote in message <A=20
=
href=3D"news:3ECDFC5E.B7E5E4F4@ca.ibm.com">news:3ECDFC5E.B7E5E4F4@ca.ibm.=
com</A>...</DIV>Remko,=20
<P>In the JETEmitter there is this line of code:=20
<BLOCKQUOTE>URLClassLoader classLoader =3D new URLClassLoader(new URL =
[] { url=20
}, JETEmitter.this.getClass().getClassLoader());</BLOCKQUOTE>Notice =
that it's=20
using the class loader of the JETEmitter class itself. =
Everywhere that=20
we use the JETEmitter in the GenModel code we use it like this:=20
<BLOCKQUOTE> interfaceEmitter =3D new =
JETEmitter(getTemplatePath(),=20
interfaceTemplateName) {};</BLOCKQUOTE>Notice that it uses an inner =
class and=20
therefore the code above will pick up the class loader that can load =
GenModel=20
classes. Without the inner classes, the classloader of the =
JETEmitter=20
itself, i.e., the classloader for the org.eclipse.emf.codegen plugin, =
and it=20
can't see much.=20
<P>Clearly this is very non-obvious, and there isn't even a speck of=20
Javadoc. I'm going to change the JETEmitter code so that the =
class=20
loader can be provided as an argument and I'm going to change the =
GenModel to=20
use it like this:=20
<BLOCKQUOTE>interfaceEmitter =3D new JETEmitter(getTemplatePath(),=20
interfaceTemplateName, getClass().getClassLoader());</BLOCKQUOTE>I =
think this=20
will make the behavior more obvious. Sorry you had to struggle =
so=20
hard... <BR> =20
<P>Remko Popma wrote:=20
<BLOCKQUOTE TYPE=3D"CITE">Ed,=20
<P>Thanks for your reply. Calling JETEmitter from a plugin action =
(like=20
<BR>org.eclipse.emf.codegen.action.CompileTemplateAction) solved =
<BR>the=20
NullPointerException problem.=20
<P>I'm not sure if it's ok to ask a new question in the same thread, =
but=20
here <BR>goes:=20
<P>From a previous post <BR>(<A=20
=
href=3D" http://www.eclipse.org/newsportal/article.php3?id=3D58&a mp;group=3D=
eclipse.tools.em"> http://www.eclipse.org/newsportal/article.php3?id=3D58&=
amp;group=3Declipse.tools.em</A>=20
<BR>f) I understood that it's possible to pass <BR>my custom model =
(that is,=20
a non-ecore model) to a template. So instead of <BR>passing a String =
argument, I now try to pass a simple bean class (extending =
<BR>Object) to=20
the template.=20
<P>This looks like it should work, but a NoClassDefFoundError gets =
thrown=20
<BR>when JETEmitter.generate() is called. <BR>This is where I got =
stuck...=20
I've added my bean class to the classpath <BR>of the .JETEmitters =
project in=20
several different ways, but it doesn't seem <BR>to make a =
difference.=20
<P>More details follow below. <BR>Any pointers would be greatly =
appreciated.=20
<P>The template looks like this: <BR><%@ jet package=3D"hello"=20
imports=3D"main.*" class=3D"HelloWorld" %> <BR><% Employee =
employee =3D=20
(Employee)argument; %> <BR>public class HelloWorld { =
<BR> public=20
static void main(String[] args) { <BR> =
System.out.println("Employee=20
name=3D<%=3D employee.getName() %>"); <BR> } <BR>}=20
<P>And the action that calls it looks like this: <BR>JETEmitter emit =
=3D new=20
JETEmitter(templateURI); <BR>Employee employee =3D new Employee(); =
<BR>String=20
result =3D emit.generate(new NullProgressMonitor(), new Object[]=20
<BR>{employee}); <BR>System.out.println(result);=20
<P>The first time I got this exception:=20
<BR>org.eclipse.emf.codegen.jet.JETException: Resource =
/.JETEmitters/runtime=20
<BR>already exists. <BR> at=20
=
org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:383)=20
<BR> at=20
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421) =
<BR> at main.Main.run(Main.java:51)=20
<P>This happened only once. <BR>Next, nothing happened when I ran my =
action,=20
until I figured out that the <BR>javajet <BR>template was compiled =
into a=20
HelloWorld.java source file correctly, but the <BR>source file could =
not=20
compile. The HelloWorld.java source file is located in <BR>a =
<BR>project=20
called .JETEmitters that gets created by JETEmitter. Adding =
<BR>Employee to=20
the classpath of the .JETEmitters project solved <BR>the compilation =
problem.=20
<P>Running my emit action again got the exception below, <BR>where =
the cause=20
seems to be a NoClassDefFoundError. <BR>---------------------=20
<BR>org.eclipse.emf.codegen.jet.JETException[0]:=20
<BR>java.lang.reflect.InvocationTargetException <BR> at=20
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) =
<BR> at=20
=
<BR> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.=
java:39=20
<BR>) <BR> at=20
=
<BR> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAcces=
sorImpl=20
<BR>.java:25) <BR> at =
java.lang.reflect.Method.invoke(Method.java:324)=20
<BR> at=20
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:429) =
<BR> at main.Main.run(Main.java:51) <BR> at=20
=
org.eclipse.ui.internal.PluginAction.runWithEvent(PluginActi on.java:251) =
<BR> at=20
=
<BR> org.eclipse.jface.action.ActionContributionItem.handleWidget Selection=
(Action=20
<BR>ContributionItem.java:456) <BR> at=20
=
<BR> org.eclipse.jface.action.ActionContributionItem.handleWidget Event(Act=
ionCont=20
<BR>ributionItem.java:403) <BR> at=20
=
<BR> org.eclipse.jface.action.ActionContributionItem.access$0(Act ionContri=
butionI=20
<BR>tem.java:397) <BR> at=20
=
<BR> org.eclipse.jface.action.ActionContributionItem$ActionListen er.handle=
Event(A=20
<BR>ctionContributionItem.java:72) <BR> at=20
org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java :81)=20
<BR> at =
org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:840)=20
<BR> at=20
org.eclipse.swt.widgets.Display.runDeferredEvents(Display.ja va:1838) =
<BR> at=20
org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :1545)=20
<BR> at=20
org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:1402)=20
<BR> at =
org.eclipse.ui.internal.Workbench.run(Workbench.java:1385)=2 0
<BR> at=20
=
<BR> org.eclipse.core.internal.boot.InternalBootLoader.run(Intern alBootLoa=
der.jav=20
<BR>a:845) <BR> at=20
org.eclipse.core.boot.BootLoader.run(BootLoader.java:461) =
<BR> at=20
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) =
<BR> at=20
=
<BR> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.=
java:39=20
<BR>) <BR> at=20
=
<BR> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAcces=
sorImpl=20
<BR>.java:25) <BR> at =
java.lang.reflect.Method.invoke(Method.java:324)=20
<BR> at org.eclipse.core.launcher.Main.basicRun(Main.java:291)=20
<BR> at org.eclipse.core.launcher.Main.run(Main.java:747) =
<BR> at=20
org.eclipse.core.launcher.Main.main(Main.java:583) <BR>Caused by:=20
java.lang.NoClassDefFoundError: main/Employee <BR> at=20
hello.HelloWorld.generate(HelloWorld.java:22) <BR> ... 26 more=20
<BR>Unhandled exception caught in event loop. <BR>Reason:=20
<BR>org.eclipse.emf.codegen.jet.JETException: =
<BR>--------------------------=20
<P>I've tried to change the way the Employee class is added to the=20
classpath, <BR>but nothing seems to make a difference. Any help =
would be=20
very welcome.=20
<P>Thanks,=20
<P>Remko Popma=20
<P>"Ed Merks" <merks@ca.ibm.com> wrote in message <BR><A=20
=
href=3D"news:3ECB64E5.A16E8DCD@ca.ibm.com">news:3ECB64E5.A16E8DCD@ca.ibm.=
com</A>...=20
<BR>> Remko, <BR>> <BR>> JET is designed to run only as a =
workspace=20
application so you must <BR>mimimally <BR>> run it as an Eclipse =
headless=20
application (so that plugin initialization <BR>takes <BR>> =
places).=20
<BR>> <BR>> <BR>> Remko Popma wrote: <BR>> <BR>> > =
Hi all,=20
<BR>> > <BR>> > Could anyone help me with this problem? =
<BR>>=20
> <BR>> > I'm trying to call "generate" on a JETEmitter =
instance,=20
<BR>> > but a NullpointerEx gets thrown in =
JETEmitter.initialize().=20
<BR>> > <BR>> > This is my code: <BR>> > <BR>> =
>=20
JETEmitter emitter =3D new JETEmitter( <BR>>=20
> &a mp;nbsp; =20
"/sandbox/templates/HelloWorld.javajet"); <BR>> > String[] =
args =3D new=20
String[] {"hi" }; <BR>> > String result =3D =
emitter.generate(new=20
NullProgressMonitor(), args); <BR>> > =
System.out.println(result);=20
<BR>> > <BR>> > And this is the stack trace: <BR>> =
>=20
<BR>> > java.lang.NullPointerException <BR>> > at=20
=
<BR> org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:169=
)=20
<BR>> > at=20
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421) =
<BR>> > at runhello.Main.main(Main.java:24) <BR>> =
>=20
Exception in thread "main" <BR>> > <BR>> > The line =
where the=20
error occurs contains "CodeGenPlugin.getPlugin()", <BR>and I =
<BR>> >=20
think that this returns null, but I don't understand why. Is the =
plugin=20
<BR>> > not activated? I did create an interface with @model =
tags,=20
generated a <BR>> > genmodel, and generated an Edit and Editor =
project=20
from that, so the <BR>plugin <BR>> > should be activated... =
<BR>>=20
> Or am I missing something else completely? <BR>> > Should =
I not=20
use JETEmitter this way? <BR>> > <BR>> > Any help would =
be very=20
welcome. <BR>> > Thanks, <BR>> > Remko Popma <BR>> =
>=20
<BR>> <BR> =20
=
------------------------------------------------------------ ------------ =
<BR>>=20
=
> &a mp;nbsp; &a mp;nb=
sp; &nb sp; =20
Name: jetsandbox.gif <BR>> > =20
jetsandbox.gif Type: GIF Image (image/gif) =
<BR>>=20
=
> &a mp;nbsp; &a mp;nb=
sp; =20
Encoding: base64 =
<BR>></P></BLOCKQUOTE></BLOCKQUOTE></BODY></HTML >
------=_NextPart_000_00F6_01C32199.3622A960--
|
|
|
| Re: getting started with JETEmitter [message #377623 is a reply to message #377621] |
Fri, 23 May 2003 17:36   |
Ed Merks Messages: 24564 Registered: July 2009 |
Senior Member |
|
|
--------------6F1D47BD443E4152D4E2753D
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Remko,
Your additional request is a very good one. I've already made the other
change and don't have time for this one right now; I'm going on vaction
for two weeks. (Yeah!) I'd suggest opening a bugzilla defect with this
request.
Remko Popma wrote:
> Ed, Thanks!Interesting hack with the inner class. I didn't notice the
> brackets in the GenModel code...An extra constructor that takes a
> classloader would be good, I agree. If you are going to change
> JETEmitter, can I make a request?Could you add some API to make it
> possible to add IClasspathEntries to the emitter before initialize is
> called?Currently all classpath entries are hard-coded (JRELIB,
> EMF_COMMON, EMF_ECORE, EMF_CODEGEN, and EMF_CODEGEN_ECORE),which kind
> of assumes that the meta model is a genModel.I would like to use my
> own meta model but there is no clean way to add my classes to the
> classpath now.An addClasspathEntry method would be great. (Come to
> think of it, perhaps the EMF classpaths don't really belong in the jet
> package. If JETEmitter has a methodto add IClasspathEntries, it might
> make sense to have a subclass of JETEmitter (GenModelEmitter or
> something, you can probablythink of a better name) in the
> org.eclipse.emf.codegen.ecore.genmodel package that would add all the
> classpathentries needed for EMF code generation. Or have a factory
> method for creating a JETEmitter instance(instead of calling "new
> JETEmitter(getTemplatePath(), templateName) { }") that creates the
> instance and adds the necessary classpath entries.This would remove
> the last genmodel dependency from the jet package...Hm... Might be a
> lot of work in the genmodel package. Oh well. Just my 2 cents.) Thanks
> again for the help.Remko
>
> "Ed Merks" <merks@ca.ibm.com> wrote in message
> news:3ECDFC5E.B7E5E4F4@ca.ibm.com...Remko,
>
> In the JETEmitter there is this line of code:
>
> URLClassLoader classLoader = new
> URLClassLoader(new URL [] { url },
> JETEmitter.this.getClass().getClassLoader());
>
> Notice that it's using the class loader of the JETEmitter
> class itself. Everywhere that we use the JETEmitter in the
> GenModel code we use it like this:
>
> interfaceEmitter = new
> JETEmitter(getTemplatePath(),
> interfaceTemplateName) {};
>
> Notice that it uses an inner class and therefore the code
> above will pick up the class loader that can load GenModel
> classes. Without the inner classes, the classloader of the
> JETEmitter itself, i.e., the classloader for the
> org.eclipse.emf.codegen plugin, and it can't see much.
>
> Clearly this is very non-obvious, and there isn't even a
> speck of Javadoc. I'm going to change the JETEmitter code
> so that the class loader can be provided as an argument and
> I'm going to change the GenModel to use it like this:
>
> interfaceEmitter = new
> JETEmitter(getTemplatePath(),
> interfaceTemplateName,
> getClass().getClassLoader());
>
> I think this will make the behavior more obvious. Sorry you
> had to struggle so hard...
>
>
> Remko Popma wrote:
>
> > Ed,
> >
> > Thanks for your reply. Calling JETEmitter from a plugin
> > action (like
> > org.eclipse.emf.codegen.action.CompileTemplateAction)
> > solved
> > the NullPointerException problem.
> >
> > I'm not sure if it's ok to ask a new question in the same
> > thread, but here
> > goes:
> >
> > From a previous post
> > ( http://www.eclipse.org/newsportal/article.php3?id=58&gro up=eclipse.tools.em
> >
> > f) I understood that it's possible to pass
> > my custom model (that is, a non-ecore model) to a
> > template. So instead of
> > passing a String argument, I now try to pass a simple bean
> > class (extending
> > Object) to the template.
> >
> > This looks like it should work, but a NoClassDefFoundError
> > gets thrown
> > when JETEmitter.generate() is called.
> > This is where I got stuck... I've added my bean class to
> > the classpath
> > of the .JETEmitters project in several different ways, but
> > it doesn't seem
> > to make a difference.
> >
> > More details follow below.
> > Any pointers would be greatly appreciated.
> >
> > The template looks like this:
> > <%@ jet package="hello" imports="main.*"
> > class="HelloWorld" %>
> > <% Employee employee = (Employee)argument; %>
> > public class HelloWorld {
> > public static void main(String[] args) {
> > System.out.println("Employee name=<%= employee.getName()
> > %>");
> > }
> > }
> >
> > And the action that calls it looks like this:
> > JETEmitter emit = new JETEmitter(templateURI);
> > Employee employee = new Employee();
> > String result = emit.generate(new NullProgressMonitor(),
> > new Object[]
> > {employee});
> > System.out.println(result);
> >
> > The first time I got this exception:
> > org.eclipse.emf.codegen.jet.JETException: Resource
> > /.JETEmitters/runtime
> > already exists.
> > at
> > org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:383)
> >
> > at
> > org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)
> >
> > at main.Main.run(Main.java:51)
> >
> > This happened only once.
> > Next, nothing happened when I ran my action, until I
> > figured out that the
> > javajet
> > template was compiled into a HelloWorld.java source file
> > correctly, but the
> > source file could not compile. The HelloWorld.java source
> > file is located in
> > a
> > project called .JETEmitters that gets created by
> > JETEmitter. Adding
> > Employee to the classpath of the .JETEmitters project
> > solved
> > the compilation problem.
> >
> > Running my emit action again got the exception below,
> > where the cause seems to be a NoClassDefFoundError.
> > ---------------------
> > org.eclipse.emf.codegen.jet.JETException[0]:
> > java.lang.reflect.InvocationTargetException
> > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
> > Method)
> > at
> > sun
> > reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessor Impl.java:39
> >
> > )
> > at
> > sun
> > reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethod AccessorImpl
> >
> > .java:25)
> > at java.lang.reflect.Method.invoke(Method.java:324)
> > at
> > org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:429)
> >
> > at main.Main.run(Main.java:51)
> > at
> > org.eclipse.ui.internal.PluginAction.runWithEvent(PluginActi on.java:251)
> >
> > at
> > org
> > eclipse.jface.action.ActionContributionItem.handleWidgetSele ction(Action
> >
> > ContributionItem.java:456)
> > at
> > org
> > eclipse.jface.action.ActionContributionItem.handleWidgetEven t(ActionCont
> >
> > ributionItem.java:403)
> > at
> > org
> > eclipse.jface.action.ActionContributionItem.access$0(ActionC ontributionI
> >
> > tem.java:397)
> > at
> > org
> > eclipse.jface.action.ActionContributionItem$ActionListener.h andleEvent(A
> >
> > ctionContributionItem.java:72)
> > at
> > org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java :81)
> >
> > at
> > org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:840)
> > at
> > org.eclipse.swt.widgets.Display.runDeferredEvents(Display.ja va:1838)
> >
> > at
> > org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :1545)
> >
> > at
> > org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:1402)
> >
> > at
> > org.eclipse.ui.internal.Workbench.run(Workbench.java:1385)
> >
> > at
> > org
> > eclipse.core.internal.boot.InternalBootLoader.run(InternalBo otLoader.jav
> >
> > a:845)
> > at
> > org.eclipse.core.boot.BootLoader.run(BootLoader.java:461)
> > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
> > Method)
> > at
> > sun
> > reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessor Impl.java:39
> >
> > )
> > at
> > sun
> > reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethod AccessorImpl
> >
> > .java:25)
> > at java.lang.reflect.Method.invoke(Method.java:324)
> > at org.eclipse.core.launcher.Main.basicRun(Main.java:291)
> >
> > at org.eclipse.core.launcher.Main.run(Main.java:747)
> > at org.eclipse.core.launcher.Main.main(Main.java:583)
> > Caused by: java.lang.NoClassDefFoundError: main/Employee
> > at hello.HelloWorld.generate(HelloWorld.java:22)
> > ... 26 more
> > Unhandled exception caught in event loop.
> > Reason:
> > org.eclipse.emf.codegen.jet.JETException:
> > --------------------------
> >
> > I've tried to change the way the Employee class is added
> > to the classpath,
> > but nothing seems to make a difference. Any help would be
> > very welcome.
> >
> > Thanks,
> >
> > Remko Popma
> >
> > "Ed Merks" <merks@ca.ibm.com> wrote in message
> > news:3ECB64E5.A16E8DCD@ca.ibm.com...
> > > Remko,
> > >
> > > JET is designed to run only as a workspace application
> > so you must
> > mimimally
> > > run it as an Eclipse headless application (so that
> > plugin initialization
> > takes
> > > places).
> > >
> > >
> > > Remko Popma wrote:
> > >
> > > > Hi all,
> > > >
> > > > Could anyone help me with this problem?
> > > >
> > > > I'm trying to call "generate" on a JETEmitter
> > instance,
> > > > but a NullpointerEx gets thrown in
> > JETEmitter.initialize().
> > > >
> > > > This is my code:
> > > >
> > > > JETEmitter emitter = new JETEmitter(
> > > > "/sandbox/templates/HelloWorld.javajet");
> > > > String[] args = new String[] {"hi" };
> > > > String result = emitter.generate(new
> > NullProgressMonitor(), args);
> > > > System.out.println(result);
> > > >
> > > > And this is the stack trace:
> > > >
> > > > java.lang.NullPointerException
> > > > at
> > org.ecl
> > pse.emf.codegen.jet.JETEmitter.initialize(JETEmitter.java:16 9)
> >
> > > > at
> > org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)
> >
> > > > at runhello.Main.main(Main.java:24)
> > > > Exception in thread "main"
> > > >
> > > > The line where the error occurs contains
> > "CodeGenPlugin.getPlugin()",
> > and I
> > > > think that this returns null, but I don't understand
> > why. Is the plugin
> > > > not activated? I did create an interface with @model
> > tags, generated a
> > > > genmodel, and generated an Edit and Editor project
> > from that, so the
> > plugin
> > > > should be activated...
> > > > Or am I missing something else completely?
> > > > Should I not use JETEmitter this way?
> > > >
> > > > Any help would be very welcome.
> > > > Thanks,
> > > > Remko Popma
> > > >
> > >
> >
> > ------------------------------------------------------------ ------------
> >
> > > > Name: jetsandbox.gif
> > > > jetsandbox.gif Type: GIF Image (image/gif)
> > > > Encoding: base64
> > >
>
--------------6F1D47BD443E4152D4E2753D
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<body bgcolor="#FFFFFF">
Remko,
<p>Your additional request is a very good one. I've already made
the other change and don't have time for this one right now; I'm going
on vaction for two weeks. (Yeah!) I'd suggest opening a bugzilla
defect with this request.
<br>
<p>Remko Popma wrote:
<blockquote TYPE=CITE><style></style>
<font face="?? ?????"><font size=-1>Ed,</font></font> <font face="?? ?????"><font size=-1>Thanks!</font></font><font face="?? ?????"><font size=-1>Interesting
hack with the inner class. I didn't notice the brackets in the GenModel
code...</font></font><font face="?? ?????"><font size=-1>An extra constructor
that takes a classloader would be good, I agree.</font></font> <font face="?? ?????"><font size=-1>If
you are going to change JETEmitter, can I make a request?</font></font><font face="?? ?????"><font size=-1>Could
you add some API to make it possible to add IClasspathEntries to the emitter
before initialize is called?</font></font><font face="?? ?????"><font size=-1>Currently
all classpath entries are hard-coded (JRELIB, EMF_COMMON, EMF_ECORE, EMF_CODEGEN,
and EMF_CODEGEN_ECORE),</font></font><font face="?? ?????"><font size=-1>which
kind of assumes that the meta model is a genModel.</font></font><font face="?? ?????"><font size=-1>I
would like to use my own meta model but there is no clean way to add my
classes to the classpath now.</font></font><font face="?? ?????"><font size=-1>An
addClasspathEntry method would be great.</font></font> <font face="?? ?????"><font size=-1>(Come
to think of it, perhaps the EMF classpaths don't really belong in the jet
package. If JETEmitter has a method</font></font><font face="?? ?????"><font size=-1>to
add IClasspathEntries, it might make sense to have a subclass of JETEmitter
(GenModelEmitter or something, you can probably</font></font><font face="?? ?????"><font size=-1>think
of a better name) in the org.eclipse.emf.codegen.ecore.genmodel package
that would add all the classpath</font></font><font face="?? ?????"><font size=-1>entries
needed for EMF code generation. Or have a factory method for creating a
JETEmitter instance</font></font><font face="?? ?????"><font size=-1>(instead
of calling "new JETEmitter(getTemplatePath(), templateName) { }") that
creates the instance and adds the necessary classpath entries.</font></font><font face="?? ?????"><font size=-1>This
would remove the last genmodel dependency from the jet package...</font></font><font face="?? ?????"><font size=-1>Hm...
Might be a lot of work in the genmodel package. Oh well. Just my 2 cents.)</font></font> <font face="?? ?????"><font size=-1>Thanks
again for the help.</font></font><font face="?? ?????"><font size=-1>Remko</font></font>
<blockquote
style="BORDER-LEFT: #000000 2px solid; MARGIN-LEFT: 5px; MARGIN-RIGHT: 0px; PADDING-LEFT: 5px; PADDING-RIGHT: 0px">"Ed
Merks" <<a href="mailto:merks@ca.ibm.com">merks@ca.ibm.com</a>> wrote
in message <a href="news:3ECDFC5E.B7E5E4F4@ca.ibm.com">news:3ECDFC5E.B7E5E4F4@ca.ibm.com</a>...Remko,
<p>In the JETEmitter there is this line of code:
<blockquote>URLClassLoader classLoader = new URLClassLoader(new URL []
{ url }, JETEmitter.this.getClass().getClassLoader());</blockquote>
Notice that it's using the class loader of the JETEmitter class itself.
Everywhere that we use the JETEmitter in the GenModel code we use it like
this:
<blockquote> interfaceEmitter = new JETEmitter(getTemplatePath(),
interfaceTemplateName) {};</blockquote>
Notice that it uses an inner class and therefore the code above will pick
up the class loader that can load GenModel classes. Without the inner
classes, the classloader of the JETEmitter itself, i.e., the classloader
for the org.eclipse.emf.codegen plugin, and it can't see much.
<p>Clearly this is very non-obvious, and there isn't even a speck of Javadoc.
I'm going to change the JETEmitter code so that the class loader can be
provided as an argument and I'm going to change the GenModel to use it
like this:
<blockquote>interfaceEmitter = new JETEmitter(getTemplatePath(), interfaceTemplateName,
getClass().getClassLoader());</blockquote>
I think this will make the behavior more obvious. Sorry you had to
struggle so hard...
<br>
<p>Remko Popma wrote:
<blockquote TYPE="CITE">Ed,
<p>Thanks for your reply. Calling JETEmitter from a plugin action (like
<br>org.eclipse.emf.codegen.action.CompileTemplateAction) solved
<br>the NullPointerException problem.
<p>I'm not sure if it's ok to ask a new question in the same thread, but
here
<br>goes:
<p>From a previous post
<br>(<a href=" http://www.eclipse.org/newsportal/article.php3?id=58&gro up=eclipse.tools.em"> http://www.eclipse.org/newsportal/article.php3?id=58&group=eclipse.tools.em</a>
<br>f) I understood that it's possible to pass
<br>my custom model (that is, a non-ecore model) to a template. So instead
of
<br>passing a String argument, I now try to pass a simple bean class (extending
<br>Object) to the template.
<p>This looks like it should work, but a NoClassDefFoundError gets thrown
<br>when JETEmitter.generate() is called.
<br>This is where I got stuck... I've added my bean class to the classpath
<br>of the .JETEmitters project in several different ways, but it doesn't
seem
<br>to make a difference.
<p>More details follow below.
<br>Any pointers would be greatly appreciated.
<p>The template looks like this:
<br><%@ jet package="hello" imports="main.*" class="HelloWorld" %>
<br><% Employee employee = (Employee)argument; %>
<br>public class HelloWorld {
<br> public static void main(String[] args) {
<br> System.out.println("Employee name=<%= employee.getName()
%>");
<br> }
<br>}
<p>And the action that calls it looks like this:
<br>JETEmitter emit = new JETEmitter(templateURI);
<br>Employee employee = new Employee();
<br>String result = emit.generate(new NullProgressMonitor(), new Object[]
<br>{employee});
<br>System.out.println(result);
<p>The first time I got this exception:
<br>org.eclipse.emf.codegen.jet.JETException: Resource /.JETEmitters/runtime
<br>already exists.
<br> at org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:383)
<br> at org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)
<br> at main.Main.run(Main.java:51)
<p>This happened only once.
<br>Next, nothing happened when I ran my action, until I figured out that
the
<br>javajet
<br>template was compiled into a HelloWorld.java source file correctly,
but the
<br>source file could not compile. The HelloWorld.java source file is located
in
<br>a
<br>project called .JETEmitters that gets created by JETEmitter. Adding
<br>Employee to the classpath of the .JETEmitters project solved
<br>the compilation problem.
<p>Running my emit action again got the exception below,
<br>where the cause seems to be a NoClassDefFoundError.
<br>---------------------
<br>org.eclipse.emf.codegen.jet.JETException[0]:
<br>java.lang.reflect.InvocationTargetException
<br> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
<br> at
<br> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.java:39
<br>)
<br> at
<br> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorImpl
<br>.java:25)
<br> at java.lang.reflect.Method.invoke(Method.java:324)
<br> at org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:429)
<br> at main.Main.run(Main.java:51)
<br> at org.eclipse.ui.internal.PluginAction.runWithEvent(PluginActi on.java:251)
<br> at
<br> org.eclipse.jface.action.ActionContributionItem.handleWidget Selection(Action
<br>ContributionItem.java:456)
<br> at
<br> org.eclipse.jface.action.ActionContributionItem.handleWidget Event(ActionCont
<br>ributionItem.java:403)
<br> at
<br> org.eclipse.jface.action.ActionContributionItem.access$0(Act ionContributionI
<br>tem.java:397)
<br> at
<br> org.eclipse.jface.action.ActionContributionItem$ActionListen er.handleEvent(A
<br>ctionContributionItem.java:72)
<br> at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java :81)
<br> at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:840)
<br> at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.ja va:1838)
<br> at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :1545)
<br> at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:1402)
<br> at org.eclipse.ui.internal.Workbench.run(Workbench.java:1385)
<br> at
<br> org.eclipse.core.internal.boot.InternalBootLoader.run(Intern alBootLoader.jav
<br>a:845)
<br> at org.eclipse.core.boot.BootLoader.run(BootLoader.java:461)
<br> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
<br> at
<br> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.java:39
<br>)
<br> at
<br> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorImpl
<br>.java:25)
<br> at java.lang.reflect.Method.invoke(Method.java:324)
<br> at org.eclipse.core.launcher.Main.basicRun(Main.java:291)
<br> at org.eclipse.core.launcher.Main.run(Main.java:747)
<br> at org.eclipse.core.launcher.Main.main(Main.java:583)
<br>Caused by: java.lang.NoClassDefFoundError: main/Employee
<br> at hello.HelloWorld.generate(HelloWorld.java:22)
<br> ... 26 more
<br>Unhandled exception caught in event loop.
<br>Reason:
<br>org.eclipse.emf.codegen.jet.JETException:
<br>--------------------------
<p>I've tried to change the way the Employee class is added to the classpath,
<br>but nothing seems to make a difference. Any help would be very welcome.
<p>Thanks,
<p>Remko Popma
<p>"Ed Merks" <merks@ca.ibm.com> wrote in message
<br><a href="news:3ECB64E5.A16E8DCD@ca.ibm.com">news:3ECB64E5.A16E8DCD@ca.ibm.com</a>...
<br>> Remko,
<br>>
<br>> JET is designed to run only as a workspace application so you must
<br>mimimally
<br>> run it as an Eclipse headless application (so that plugin initialization
<br>takes
<br>> places).
<br>>
<br>>
<br>> Remko Popma wrote:
<br>>
<br>> > Hi all,
<br>> >
<br>> > Could anyone help me with this problem?
<br>> >
<br>> > I'm trying to call "generate" on a JETEmitter instance,
<br>> > but a NullpointerEx gets thrown in JETEmitter.initialize().
<br>> >
<br>> > This is my code:
<br>> >
<br>> > JETEmitter emitter = new JETEmitter(
<br>> > "/sandbox/templates/HelloWorld.javajet");
<br>> > String[] args = new String[] {"hi" };
<br>> > String result = emitter.generate(new NullProgressMonitor(), args);
<br>> > System.out.println(result);
<br>> >
<br>> > And this is the stack trace:
<br>> >
<br>> > java.lang.NullPointerException
<br>> > at
<br> org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:169)
<br>> > at org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)
<br>> > at runhello.Main.main(Main.java:24)
<br>> > Exception in thread "main"
<br>> >
<br>> > The line where the error occurs contains "CodeGenPlugin.getPlugin()",
<br>and I
<br>> > think that this returns null, but I don't understand why. Is the
plugin
<br>> > not activated? I did create an interface with @model tags, generated
a
<br>> > genmodel, and generated an Edit and Editor project from that, so
the
<br>plugin
<br>> > should be activated...
<br>> > Or am I missing something else completely?
<br>> > Should I not use JETEmitter this way?
<br>> >
<br>> > Any help would be very welcome.
<br>> > Thanks,
<br>> > Remko Popma
<br>> >
<br>>
<br> ------------------------------------------------------------ ------------
<br>> >
Name: jetsandbox.gif
<br>> > jetsandbox.gif Type: GIF Image
(image/gif)
<br>> >
Encoding: base64
<br>></blockquote>
</blockquote>
</blockquote>
</body>
</html>
--------------6F1D47BD443E4152D4E2753D--
|
|
|
| Re: getting started with JETEmitter [message #377628 is a reply to message #377623] |
Fri, 23 May 2003 20:22   |
|
Originally posted by: remko.popma.azzurri.jp
This is a multi-part message in MIME format.
------=_NextPart_000_013A_01C321D5.FEEF6B80
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Ed,
I added the bug to bugzilla:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=38069
Enjoy your vacation.
Remko
"Ed Merks" <merks@ca.ibm.com> wrote in message
news:3ECE9442.AB37EEC3@ca.ibm.com...
Remko,
Your additional request is a very good one. I've already made the other
change and don't have time for this one right now; I'm going on vaction for
two weeks. (Yeah!) I'd suggest opening a bugzilla defect with this request.
Remko Popma wrote:
Ed, Thanks!Interesting hack with the inner class. I didn't notice the
brackets in the GenModel code...An extra constructor that takes a
classloader would be good, I agree. If you are going to change JETEmitter,
can I make a request?Could you add some API to make it possible to add
IClasspathEntries to the emitter before initialize is called?Currently all
classpath entries are hard-coded (JRELIB, EMF_COMMON, EMF_ECORE,
EMF_CODEGEN, and EMF_CODEGEN_ECORE),which kind of assumes that the meta
model is a genModel.I would like to use my own meta model but there is no
clean way to add my classes to the classpath now.An addClasspathEntry method
would be great. (Come to think of it, perhaps the EMF classpaths don't
really belong in the jet package. If JETEmitter has a methodto add
IClasspathEntries, it might make sense to have a subclass of JETEmitter
(GenModelEmitter or something, you can probablythink of a better name) in
the org.eclipse.emf.codegen.ecore.genmodel package that would add all the
classpathentries needed for EMF code generation. Or have a factory method
for creating a JETEmitter instance(instead of calling "new
JETEmitter(getTemplatePath(), templateName) { }") that creates the instance
and adds the necessary classpath entries.This would remove the last genmodel
dependency from the jet package...Hm... Might be a lot of work in the
genmodel package. Oh well. Just my 2 cents.) Thanks again for the help.Remko
"Ed Merks" <merks@ca.ibm.com> wrote in message
news:3ECDFC5E.B7E5E4F4@ca.ibm.com...Remko,
In the JETEmitter there is this line of code:
URLClassLoader classLoader = new URLClassLoader(new URL [] { url },
JETEmitter.this.getClass().getClassLoader());
Notice that it's using the class loader of the JETEmitter class
itself. Everywhere that we use the JETEmitter in the GenModel code we use
it like this:
interfaceEmitter = new JETEmitter(getTemplatePath(),
interfaceTemplateName) {};
Notice that it uses an inner class and therefore the code above will
pick up the class loader that can load GenModel classes. Without the inner
classes, the classloader of the JETEmitter itself, i.e., the classloader for
the org.eclipse.emf.codegen plugin, and it can't see much.
Clearly this is very non-obvious, and there isn't even a speck of
Javadoc. I'm going to change the JETEmitter code so that the class loader
can be provided as an argument and I'm going to change the GenModel to use
it like this:
interfaceEmitter = new JETEmitter(getTemplatePath(),
interfaceTemplateName, getClass().getClassLoader());
I think this will make the behavior more obvious. Sorry you had to
struggle so hard...
Remko Popma wrote:
Ed,
Thanks for your reply. Calling JETEmitter from a plugin action (like
org.eclipse.emf.codegen.action.CompileTemplateAction) solved
the NullPointerException problem.
I'm not sure if it's ok to ask a new question in the same thread,
but here
goes:
From a previous post
( http://www.eclipse.org/newsportal/article.php3?id=58&gro up=eclipse.tools.em
f) I understood that it's possible to pass
my custom model (that is, a non-ecore model) to a template. So
instead of
passing a String argument, I now try to pass a simple bean class
(extending
Object) to the template.
This looks like it should work, but a NoClassDefFoundError gets
thrown
when JETEmitter.generate() is called.
This is where I got stuck... I've added my bean class to the
classpath
of the .JETEmitters project in several different ways, but it
doesn't seem
to make a difference.
More details follow below.
Any pointers would be greatly appreciated.
The template looks like this:
<%@ jet package="hello" imports="main.*" class="HelloWorld" %>
<% Employee employee = (Employee)argument; %>
public class HelloWorld
public static void main(String[] args)
System.out.println("Employee name=<%= employee.getName() %>");
}
}
And the action that calls it looks like this:
JETEmitter emit = new JETEmitter(templateURI);
Employee employee = new Employee();
String result = emit.generate(new NullProgressMonitor(), new
Object[]
{employee});
System.out.println(result);
The first time I got this exception:
org.eclipse.emf.codegen.jet.JETException: Resource
/.JETEmitters/runtime
already exists.
at
org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:383)
at
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)
at main.Main.run(Main.java:51)
This happened only once.
Next, nothing happened when I ran my action, until I figured out
that the
javajet
template was compiled into a HelloWorld.java source file correctly,
but the
source file could not compile. The HelloWorld.java source file is
located in
a
project called .JETEmitters that gets created by JETEmitter. Adding
Employee to the classpath of the .JETEmitters project solved
the compilation problem.
Running my emit action again got the exception below,
where the cause seems to be a NoClassDefFoundError.
---------------------
org.eclipse.emf.codegen.jet.JETException[0]:
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.java:39
)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorImpl
.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:429)
at main.Main.run(Main.java:51)
at
org.eclipse.ui.internal.PluginAction.runWithEvent(PluginActi on.java:251)
at
org.eclipse.jface.action.ActionContributionItem.handleWidget Selection(Action
ContributionItem.java:456)
at
org.eclipse.jface.action.ActionContributionItem.handleWidget Event(ActionCont
ributionItem.java:403)
at
org.eclipse.jface.action.ActionContributionItem.access$0(Act ionContributionI
tem.java:397)
at
org.eclipse.jface.action.ActionContributionItem$ActionListen er.handleEvent(A
ctionContributionItem.java:72)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java :81)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:840)
at
org.eclipse.swt.widgets.Display.runDeferredEvents(Display.ja va:1838)
at
org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :1545)
at
org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:1402)
at org.eclipse.ui.internal.Workbench.run(Workbench.java:1385)
at
org.eclipse.core.internal.boot.InternalBootLoader.run(Intern alBootLoader.jav
a:845)
at org.eclipse.core.boot.BootLoader.run(BootLoader.java:461)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.java:39
)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorImpl
.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.eclipse.core.launcher.Main.basicRun(Main.java:291)
at org.eclipse.core.launcher.Main.run(Main.java:747)
at org.eclipse.core.launcher.Main.main(Main.java:583)
Caused by: java.lang.NoClassDefFoundError: main/Employee
at hello.HelloWorld.generate(HelloWorld.java:22)
... 26 more
Unhandled exception caught in event loop.
Reason:
org.eclipse.emf.codegen.jet.JETException:
--------------------------
I've tried to change the way the Employee class is added to the
classpath,
but nothing seems to make a difference. Any help would be very
welcome.
Thanks,
Remko Popma
"Ed Merks" <merks@ca.ibm.com> wrote in message
news:3ECB64E5.A16E8DCD@ca.ibm.com...
> Remko,
>
> JET is designed to run only as a workspace application so you must
mimimally
> run it as an Eclipse headless application (so that plugin
initialization
takes
> places).
>
>
> Remko Popma wrote:
>
> > Hi all,
> >
> > Could anyone help me with this problem?
> >
> > I'm trying to call "generate" on a JETEmitter instance,
> > but a NullpointerEx gets thrown in JETEmitter.initialize().
> >
> > This is my code:
> >
> > JETEmitter emitter = new
Emitter(
> > "/sandbox/templates/HelloWorld.javajet");
> > String[] args = new String[] {"hi" };
> > String result = emitter.generate(new NullProgressMonitor(), args);
> > System.out.println(result);
> >
> > And this is the stack trace:
> >
> > java.lang.NullPointerException
> > at
org.eclipse.emf.codegen.jet.JETEmitter.initializ
e(JETEmitter.java:169)
> > at
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)
> > at runhello.Main.main(Main.java:24)
> > Exception in thread "main"
> >
> > The line where the error occurs contains
"CodeGenPlugin.getPlugin()",
and I
> > think that this returns null, but I don't understand why. Is the
plugin
> > not activated? I did create an interface with @model tags,
generated a
> > genmodel, and generated an Edit and Editor project from that, so
the
plugin
> > should be activated...
> > Or am I missing something else completely?
> > Should I not use JETEmitter this way?
> >
> > Any help would be very welcome.
> > Thanks,
> > Remko Popma
> >
>
------------------------------------------------------------ ------
------
> > Name: jetsandbox.gif
> > jetsandbox.gif Type: GIF Image (image/gif)
> > Encoding: base64
>
------=_NextPart_000_013A_01C321D5.FEEF6B80
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content=3D"text/html; charset=3Diso-8859-1" =
http-equiv=3DContent-Type>
<META content=3D"MSHTML 5.00.2920.0" name=3DGENERATOR></HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Ed,</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>I added the bug to =
bugzilla: </FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2><TT><A=20
href=3D"https://bugs.eclipse.org/bugs/show_bug.cgi?id=3D38069"=20
target=3D_blank>https://bugs.eclipse.org/bugs/show_bug.cgi?id=3D38069</A>=
<BR></TT></FONT></DIV>
<DIV><FONT size=3D2><TT><FONT face=3D"MS =
Pゴシック ">Enjoy your=20
vacation.</FONT></TT></FONT></DIV>
<DIV><FONT size=3D2><TT></TT></FONT> </DIV>
<DIV><FONT size=3D2><TT><FONT face=3D"MS =
Pゴシック ">Remko</FONT></TT></FONT></DIV>
<DIV><FONT size=3D2><TT> </DIV></TT></FONT>
<BLOCKQUOTE=20
style=3D"BORDER-LEFT: #000000 2px solid; MARGIN-LEFT: 5px; MARGIN-RIGHT: =
0px; PADDING-LEFT: 5px; PADDING-RIGHT: 0px">
<DIV>"Ed Merks" <<A =
href=3D"mailto:merks@ca.ibm.com">merks@ca.ibm.com</A>>=20
wrote in message <A=20
=
href=3D"news:3ECE9442.AB37EEC3@ca.ibm.com">news:3ECE9442.AB37EEC3@ca.ibm.=
com</A>...</DIV>Remko,=20
<P>Your additional request is a very good one. I've already made =
the=20
other change and don't have time for this one right now; I'm going on =
vaction=20
for two weeks. (Yeah!) I'd suggest opening a bugzilla defect =
with this=20
request. <BR> =20
<P>Remko Popma wrote:=20
<BLOCKQUOTE TYPE=3D"CITE">
<STYLE></STYLE>
<FONT face=3D"?? ?????"><FONT size=3D-1>Ed,</FONT></FONT> <FONT =
face=3D"?? ?????"><FONT size=3D-1>Thanks!</FONT></FONT><FONT=20
face=3D"?? ?????"><FONT size=3D-1>Interesting hack with the inner =
class. I=20
didn't notice the brackets in the GenModel =
code...</FONT></FONT><FONT=20
face=3D"?? ?????"><FONT size=3D-1>An extra constructor that takes a =
classloader=20
would be good, I agree.</FONT></FONT> <FONT face=3D"?? =
?????"><FONT=20
size=3D-1>If you are going to change JETEmitter, can I make a=20
request?</FONT></FONT><FONT face=3D"?? ?????"><FONT size=3D-1>Could =
you add some=20
API to make it possible to add IClasspathEntries to the emitter =
before=20
initialize is called?</FONT></FONT><FONT face=3D"?? ?????"><FONT=20
size=3D-1>Currently all classpath entries are hard-coded (JRELIB, =
EMF_COMMON,=20
EMF_ECORE, EMF_CODEGEN, and EMF_CODEGEN_ECORE),</FONT></FONT><FONT=20
face=3D"?? ?????"><FONT size=3D-1>which kind of assumes that the =
meta model is a=20
genModel.</FONT></FONT><FONT face=3D"?? ?????"><FONT size=3D-1>I =
would like to=20
use my own meta model but there is no clean way to add my classes to =
the=20
classpath now.</FONT></FONT><FONT face=3D"?? ?????"><FONT =
size=3D-1>An=20
addClasspathEntry method would be =
great.</FONT></FONT> <FONT=20
face=3D"?? ?????"><FONT size=3D-1>(Come to think of it, perhaps the =
EMF=20
classpaths don't really belong in the jet package. If JETEmitter has =
a=20
method</FONT></FONT><FONT face=3D"?? ?????"><FONT size=3D-1>to add=20
IClasspathEntries, it might make sense to have a subclass of =
JETEmitter=20
(GenModelEmitter or something, you can probably</FONT></FONT><FONT=20
face=3D"?? ?????"><FONT size=3D-1>think of a better name) in the=20
org.eclipse.emf.codegen.ecore.genmodel package that would add all =
the=20
classpath</FONT></FONT><FONT face=3D"?? ?????"><FONT =
size=3D-1>entries needed=20
for EMF code generation. Or have a factory method for creating a =
JETEmitter=20
instance</FONT></FONT><FONT face=3D"?? ?????"><FONT =
size=3D-1>(instead of=20
calling "new JETEmitter(getTemplatePath(), templateName) { }") that =
creates=20
the instance and adds the necessary classpath =
entries.</FONT></FONT><FONT=20
face=3D"?? ?????"><FONT size=3D-1>This would remove the last =
genmodel dependency=20
from the jet package...</FONT></FONT><FONT face=3D"?? ?????"><FONT=20
size=3D-1>Hm... Might be a lot of work in the genmodel package. Oh =
well. Just=20
my 2 cents.)</FONT></FONT> <FONT face=3D"?? ?????"><FONT =
size=3D-1>Thanks=20
again for the help.</FONT></FONT><FONT face=3D"?? ?????"><FONT=20
size=3D-1>Remko</FONT></FONT> =20
<BLOCKQUOTE=20
style=3D"BORDER-LEFT: #000000 2px solid; MARGIN-LEFT: 5px; =
MARGIN-RIGHT: 0px; PADDING-LEFT: 5px; PADDING-RIGHT: 0px">"Ed=20
Merks" <<A =
href=3D"mailto:merks@ca.ibm.com">merks@ca.ibm.com</A>>=20
wrote in message <A=20
=
href=3D"news:3ECDFC5E.B7E5E4F4@ca.ibm.com">news:3ECDFC5E.B7E5E4F4@ca.ibm.=
com</A>...Remko,=20
<P>In the JETEmitter there is this line of code:=20
<BLOCKQUOTE>URLClassLoader classLoader =3D new URLClassLoader(new =
URL [] {=20
url }, =
JETEmitter.this.getClass().getClassLoader());</BLOCKQUOTE>Notice=20
that it's using the class loader of the JETEmitter class =
itself. =20
Everywhere that we use the JETEmitter in the GenModel code we use =
it like=20
this:=20
<BLOCKQUOTE> interfaceEmitter =3D new =
JETEmitter(getTemplatePath(),=20
interfaceTemplateName) {};</BLOCKQUOTE>Notice that it uses an =
inner class=20
and therefore the code above will pick up the class loader that =
can load=20
GenModel classes. Without the inner classes, the classloader =
of the=20
JETEmitter itself, i.e., the classloader for the =
org.eclipse.emf.codegen=20
plugin, and it can't see much.=20
<P>Clearly this is very non-obvious, and there isn't even a speck =
of=20
Javadoc. I'm going to change the JETEmitter code so that the =
class=20
loader can be provided as an argument and I'm going to change the =
GenModel=20
to use it like this:=20
<BLOCKQUOTE>interfaceEmitter =3D new JETEmitter(getTemplatePath(), =
interfaceTemplateName, =
getClass().getClassLoader());</BLOCKQUOTE>I think=20
this will make the behavior more obvious. Sorry you had to =
struggle=20
so hard... <BR> =20
<P>Remko Popma wrote:=20
<BLOCKQUOTE TYPE=3D"CITE">Ed,=20
<P>Thanks for your reply. Calling JETEmitter from a plugin =
action (like=20
<BR>org.eclipse.emf.codegen.action.CompileTemplateAction) solved =
<BR>the=20
NullPointerException problem.=20
<P>I'm not sure if it's ok to ask a new question in the same =
thread, but=20
here <BR>goes:=20
<P>From a previous post <BR>(<A=20
=
href=3D" http://www.eclipse.org/newsportal/article.php3?id=3D58&a mp;group=3D=
eclipse.tools.em"> http://www.eclipse.org/newsportal/article.php3?id=3D58&=
amp;group=3Declipse.tools.em</A>=20
<BR>f) I understood that it's possible to pass <BR>my custom =
model (that=20
is, a non-ecore model) to a template. So instead of <BR>passing =
a String=20
argument, I now try to pass a simple bean class (extending =
<BR>Object)=20
to the template.=20
<P>This looks like it should work, but a NoClassDefFoundError =
gets=20
thrown <BR>when JETEmitter.generate() is called. <BR>This is =
where I got=20
stuck... I've added my bean class to the classpath <BR>of the=20
.JETEmitters project in several different ways, but it doesn't =
seem=20
<BR>to make a difference.=20
<P>More details follow below. <BR>Any pointers would be greatly=20
appreciated.=20
<P>The template looks like this: <BR><%@ jet =
package=3D"hello"=20
imports=3D"main.*" class=3D"HelloWorld" %> <BR><% Employee =
employee =3D=20
(Employee)argument; %> <BR>public class HelloWorld { =
<BR> public=20
static void main(String[] args) { <BR> =20
System.out.println("Employee name=3D<%=3D employee.getName() =
%>");=20
<BR> } <BR>}=20
<P>And the action that calls it looks like this: <BR>JETEmitter =
emit =3D=20
new JETEmitter(templateURI); <BR>Employee employee =3D new =
Employee();=20
<BR>String result =3D emit.generate(new NullProgressMonitor(), =
new=20
Object[] <BR>{employee}); <BR>System.out.println(result);=20
<P>The first time I got this exception:=20
<BR>org.eclipse.emf.codegen.jet.JETException: Resource=20
/.JETEmitters/runtime <BR>already exists. <BR> at=20
=
org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:383)=20
<BR> at=20
=
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)=20
<BR> at main.Main.run(Main.java:51)=20
<P>This happened only once. <BR>Next, nothing happened when I =
ran my=20
action, until I figured out that the <BR>javajet <BR>template =
was=20
compiled into a HelloWorld.java source file correctly, but the=20
<BR>source file could not compile. The HelloWorld.java source =
file is=20
located in <BR>a <BR>project called .JETEmitters that gets =
created by=20
JETEmitter. Adding <BR>Employee to the classpath of the =
..JETEmitters=20
project solved <BR>the compilation problem.=20
<P>Running my emit action again got the exception below, =
<BR>where the=20
cause seems to be a NoClassDefFoundError. =
<BR>---------------------=20
<BR>org.eclipse.emf.codegen.jet.JETException[0]:=20
<BR>java.lang.reflect.InvocationTargetException <BR> at=20
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) =
<BR> at=20
=
<BR> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.=
java:39=20
<BR>) <BR> at=20
=
<BR> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAcces=
sorImpl=20
<BR>.java:25) <BR> at=20
java.lang.reflect.Method.invoke(Method.java:324) <BR> at=20
=
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:429)=20
<BR> at main.Main.run(Main.java:51) <BR> at=20
=
org.eclipse.ui.internal.PluginAction.runWithEvent(PluginActi on.java:251) =
<BR> at=20
=
<BR> org.eclipse.jface.action.ActionContributionItem.handleWidget Selection=
(Action=20
<BR>ContributionItem.java:456) <BR> at=20
=
<BR> org.eclipse.jface.action.ActionContributionItem.handleWidget Event(Act=
ionCont=20
<BR>ributionItem.java:403) <BR> at=20
=
<BR> org.eclipse.jface.action.ActionContributionItem.access$0(Act ionContri=
butionI=20
<BR>tem.java:397) <BR> at=20
=
<BR> org.eclipse.jface.action.ActionContributionItem$ActionListen er.handle=
Event(A=20
<BR>ctionContributionItem.java:72) <BR> at=20
org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java :81) =
<BR> at =
org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:840)=20
<BR> at=20
=
org.eclipse.swt.widgets.Display.runDeferredEvents(Display.ja va:1838)=20
<BR> at=20
=
org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :1545)=20
<BR> at=20
=
org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:1402)=20
<BR> at =
org.eclipse.ui.internal.Workbench.run(Workbench.java:1385)=2 0
<BR> at=20
=
<BR> org.eclipse.core.internal.boot.InternalBootLoader.run(Intern alBootLoa=
der.jav=20
<BR>a:845) <BR> at=20
org.eclipse.core.boot.BootLoader.run(BootLoader.java:461) =
<BR> at=20
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) =
<BR> at=20
=
<BR> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.=
java:39=20
<BR>) <BR> at=20
=
<BR> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAcces=
sorImpl=20
<BR>.java:25) <BR> at=20
java.lang.reflect.Method.invoke(Method.java:324) <BR> at=20
org.eclipse.core.launcher.Main.basicRun(Main.java:291) =
<BR> at=20
org.eclipse.core.launcher.Main.run(Main.java:747) <BR> at=20
org.eclipse.core.launcher.Main.main(Main.java:583) <BR>Caused =
by:=20
java.lang.NoClassDefFoundError: main/Employee <BR> at=20
hello.HelloWorld.generate(HelloWorld.java:22) <BR> ... 26 =
more=20
<BR>Unhandled exception caught in event loop. <BR>Reason:=20
<BR>org.eclipse.emf.codegen.jet.JETException:=20
<BR>--------------------------=20
<P>I've tried to change the way the Employee class is added to =
the=20
classpath, <BR>but nothing seems to make a difference. Any help =
would be=20
very welcome.=20
<P>Thanks,=20
<P>Remko Popma=20
<P>"Ed Merks" <merks@ca.ibm.com> wrote in message <BR><A=20
=
href=3D"news:3ECB64E5.A16E8DCD@ca.ibm.com">news:3ECB64E5.A16E8DCD@ca.ibm.=
com</A>...=20
<BR>> Remko, <BR>> <BR>> JET is designed to run only as =
a=20
workspace application so you must <BR>mimimally <BR>> run it =
as an=20
Eclipse headless application (so that plugin initialization =
<BR>takes=20
<BR>> places). <BR>> <BR>> <BR>> Remko Popma wrote: =
<BR>>=20
<BR>> > Hi all, <BR>> > <BR>> > Could anyone =
help me=20
with this problem? <BR>> > <BR>> > I'm trying to =
call=20
"generate" on a JETEmitter instance, <BR>> > but a =
NullpointerEx=20
gets thrown in JETEmitter.initialize(). <BR>> > <BR>> =
> This=20
is my code: <BR>> > <BR>> > JETEmitter emitter =3D =
new=20
JETEmitter( <BR>>=20
> &a mp;nbsp; =20
"/sandbox/templates/HelloWorld.javajet"); <BR>> > String[] =
args =3D=20
new String[] {"hi" }; <BR>> > String result =3D =
emitter.generate(new=20
NullProgressMonitor(), args); <BR>> > =
System.out.println(result);=20
<BR>> > <BR>> > And this is the stack trace: =
<BR>> >=20
<BR>> > java.lang.NullPointerException <BR>> > =
at=20
=
<BR> org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:169=
)=20
<BR>> > at=20
=
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)=20
<BR>> > at runhello.Main.main(Main.java:24) <BR>> =
>=20
Exception in thread "main" <BR>> > <BR>> > The line =
where=20
the error occurs contains "CodeGenPlugin.getPlugin()", <BR>and I =
<BR>> > think that this returns null, but I don't =
understand why.=20
Is the plugin <BR>> > not activated? I did create an =
interface=20
with @model tags, generated a <BR>> > genmodel, and =
generated an=20
Edit and Editor project from that, so the <BR>plugin <BR>> =
>=20
should be activated... <BR>> > Or am I missing something =
else=20
completely? <BR>> > Should I not use JETEmitter this way? =
<BR>>=20
> <BR>> > Any help would be very welcome. <BR>> > =
Thanks,=20
<BR>> > Remko Popma <BR>> > <BR>> <BR> =20
=
------------------------------------------------------------ ------------ =
<BR>>=20
=
> &a mp;nbsp; &a mp;nb=
sp; &nb sp; =20
Name: jetsandbox.gif <BR>> > =20
jetsandbox.gif Type: GIF Image (image/gif) =
<BR>>=20
=
> &a mp;nbsp; &a mp;nb=
sp; =20
Encoding: base64=20
<BR>></P></BLOCKQUOTE></BLOCKQUOTE></BLOCKQUOTE> </BLOCKQUOTE></BODY></=
HTML>
------=_NextPart_000_013A_01C321D5.FEEF6B80--
|
|
|
| Re: getting started with JETEmitter [message #377629 is a reply to message #377628] |
Sat, 24 May 2003 06:37   |
|
Originally posted by: remko.popma.azzurri.jp
This is a multi-part message in MIME format.
------=_NextPart_000_016F_01C3222B.F86B3720
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Sorry, I said bug I meant I added the feature request.
"Remko Popma" <remko.popma@azzurri.jp> wrote in message
news:bame1f$ht6$1@rogue.oti.com...
Ed,
I added the bug to bugzilla:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=38069
Enjoy your vacation.
Remko
"Ed Merks" <merks@ca.ibm.com> wrote in message
news:3ECE9442.AB37EEC3@ca.ibm.com...
Remko,
Your additional request is a very good one. I've already made the other
change and don't have time for this one right now; I'm going on vaction for
two weeks. (Yeah!) I'd suggest opening a bugzilla defect with this request.
Remko Popma wrote:
Ed, Thanks!Interesting hack with the inner class. I didn't notice the
brackets in the GenModel code...An extra constructor that takes a
classloader would be good, I agree. If you are going to change JETEmitter,
can I make a request?Could you add some API to make it possible to add
IClasspathEntries to the emitter before initialize is called?Currently all
classpath entries are hard-coded (JRELIB, EMF_COMMON, EMF_ECORE,
EMF_CODEGEN, and EMF_CODEGEN_ECORE),which kind of assumes that the meta
model is a genModel.I would like to use my own meta model but there is no
clean way to add my classes to the classpath now.An addClasspathEntry method
would be great. (Come to think of it, perhaps the EMF classpaths don't
really belong in the jet package. If JETEmitter has a methodto add
IClasspathEntries, it might make sense to have a subclass of JETEmitter
(GenModelEmitter or something, you can probablythink of a better name) in
the org.eclipse.emf.codegen.ecore.genmodel package that would add all the
classpathentries needed for EMF code generation. Or have a factory method
for creating a JETEmitter instance(instead of calling "new
JETEmitter(getTemplatePath(), templateName) { }") that creates the instance
and adds the necessary classpath entries.This would remove the last genmodel
dependency from the jet package...Hm... Might be a lot of work in the
genmodel package. Oh well. Just my 2 cents.) Thanks again for the help.Remko
"Ed Merks" <merks@ca.ibm.com> wrote in message
news:3ECDFC5E.B7E5E4F4@ca.ibm.com...Remko,
In the JETEmitter there is this line of code:
URLClassLoader classLoader = new URLClassLoader(new URL []
{ url }, JETEmitter.this.getClass().getClassLoader());
Notice that it's using the class loader of the JETEmitter class
itself. Everywhere that we use the JETEmitter in the GenModel code we use
it like this:
interfaceEmitter = new JETEmitter(getTemplatePath(),
interfaceTemplateName) {};
Notice that it uses an inner class and therefore the code above will
pick up the class loader that can load GenModel classes. Without the inner
classes, the classloader of the JETEmitter itself, i.e., the classloader for
the org.eclipse.emf.codegen plugin, and it can't see much.
Clearly this is very non-obvious, and there isn't even a speck of
Javadoc. I'm going to change the JETEmitter code so that the class loader
can be provided as an argument and I'm going to change the GenModel to use
it like this:
interfaceEmitter = new JETEmitter(getTemplatePath(),
interfaceTemplateName, getClass().getClassLoader());
I think this will make the behavior more obvious. Sorry you had to
struggle so hard...
Remko Popma wrote:
Ed,
Thanks for your reply. Calling JETEmitter from a plugin action
(like
org.eclipse.emf.codegen.action.CompileTemplateAction) solved
the NullPointerException problem.
I'm not sure if it's ok to ask a new question in the same thread,
but here
goes:
From a previous post
( http://www.eclipse.org/newsportal/article.php3?id=58&gro up=eclipse.tools.em
f) I understood that it's possible to pass
my custom model (that is, a non-ecore model) to a template. So
instead of
passing a String argument, I now try to pass a simple bean class
(extending
Object) to the template.
This looks like it should work, but a NoClassDefFoundError gets
thrown
when JETEmitter.generate() is called.
This is where I got stuck... I've added my bean class to the
classpath
of the .JETEmitters project in several different ways, but it
doesn't seem
to make a difference.
More details follow below.
Any pointers would be greatly appreciated.
The template looks like this:
<%@ jet package="hello" imports="main.*" class="HelloWorld" %>
<% Employee employee = (Employee)argument; %>
public class HelloWorld
public static void main(String[] args)
System.out.println("Employee name=<%= employee.getName() %>");
}
}
And the action that calls it looks like this:
JETEmitter emit = new JETEmitter(templateURI);
Employee employee = new Employee();
String result = emit.generate(new NullProgressMonitor(), new
Object[]
{employee});
System.out.println(result);
The first time I got this exception:
org.eclipse.emf.codegen.jet.JETException: Resource
/.JETEmitters/runtime
already exists.
at
org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:383)
at
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)
at main.Main.run(Main.java:51)
This happened only once.
Next, nothing happened when I ran my action, until I figured out
that the
javajet
template was compiled into a HelloWorld.java source file
correctly, but the
source file could not compile. The HelloWorld.java source file is
located in
a
project called .JETEmitters that gets created by JETEmitter.
Adding
Employee to the classpath of the .JETEmitters project solved
the compilation problem.
Running my emit action again got the exception below,
where the cause seems to be a NoClassDefFoundError.
---------------------
org.eclipse.emf.codegen.jet.JETException[0]:
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.java:39
)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorImpl
.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:429)
at main.Main.run(Main.java:51)
at
org.eclipse.ui.internal.PluginAction.runWithEvent(PluginActi on.java:251)
at
org.eclipse.jface.action.ActionContributionItem.handleWidget Selection(Action
ContributionItem.java:456)
at
org.eclipse.jface.action.ActionContributionItem.handleWidget Event(ActionCont
ributionItem.java:403)
at
org.eclipse.jface.action.ActionContributionItem.access$0(Act ionContributionI
tem.java:397)
at
org.eclipse.jface.action.ActionContributionItem$ActionListen er.handleEvent(A
ctionContributionItem.java:72)
at
org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java :81)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:840)
at
org.eclipse.swt.widgets.Display.runDeferredEvents(Display.ja va:1838)
at
org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :1545)
at
org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:1402)
at org.eclipse.ui.internal.Workbench.run(Workbench.java:1385)
at
org.eclipse.core.internal.boot.InternalBootLoader.run(Intern alBootLoader.jav
a:845)
at org.eclipse.core.boot.BootLoader.run(BootLoader.java:461)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.java:39
)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorImpl
.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.eclipse.core.launcher.Main.basicRun(Main.java:291)
at org.eclipse.core.launcher.Main.run(Main.java:747)
at org.eclipse.core.launcher.Main.main(Main.java:583)
Caused by: java.lang.NoClassDefFoundError: main/Employee
at hello.HelloWorld.generate(HelloWorld.java:22)
... 26 more
Unhandled exception caught in event loop.
Reason:
org.eclipse.emf.codegen.jet.JETException:
--------------------------
I've tried to change the way the Employee class is added to the
classpath,
but nothing seems to make a difference. Any help would be very
welcome.
Thanks,
Remko Popma
"Ed Merks" <merks@ca.ibm.com> wrote in message
news:3ECB64E5.A16E8DCD@ca.ibm.com...
> Remko,
>
> JET is designed to run only as a workspace application so you
must
mimimally
> run it as an Eclipse headless application (so that plugin
initialization
takes
> places).
>
>
> Remko Popma wrote:
>
> > Hi all,
> >
> > Could anyone help me with this problem?
> >
> > I'm trying to call "generate" on a JETEmitter instance,
> > but a NullpointerEx gets thrown in JETEmitter.initialize().
> >
> > This is my code:
> >
> > JETEmitter emitter = new
Emitter(
> > "/sandbox/templates/HelloWorld.javajet");
> > String[] args = new String[] {"hi" };
> > String result = emitter.generate(new NullProgressMonitor(), args);
> > System.out.println(result);
> >
> > And this is the stack trace:
> >
> > java.lang.NullPointerException
> > at
org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:169)
> > at org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)
> > at runhello.Main.main(Main.java:24)
> > Exception in thread "main"
> >
> > The line where the error occurs contains "CodeGenPlugin.getPlugin()",
and I
> > think that this returns null, but I don't understand why. Is the plugin
> > not activated? I did create an interface with @model tags, generated a
> > genmodel, and generated an Edit and Editor project from that, so the
plugin
> > should be activated...
> > Or am I missing something else completely?
> > Should I not use JETEmitter this way?
> >
> > Any help would be very welcome.
> > Thanks,
> > Remko Popma
> >
>
------------------------------------------------------------ ------------
> > Name: jetsandbox.gif
> > jetsandbox.gif Type: GIF Image (image/gif)
> > Encoding: base64
>
------=_NextPart_000_016F_01C3222B.F86B3720
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content=3D"text/html; charset=3Diso-8859-1" =
http-equiv=3DContent-Type>
<META content=3D"MSHTML 5.00.2920.0" name=3DGENERATOR></HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Sorry, I said bug I =
meant I added the feature=20
request.</FONT></DIV>
<BLOCKQUOTE=20
style=3D"BORDER-LEFT: #000000 2px solid; MARGIN-LEFT: 5px; MARGIN-RIGHT: =
0px; PADDING-LEFT: 5px; PADDING-RIGHT: 0px">
<DIV>"Remko Popma" <<A=20
href=3D"mailto:remko.popma@azzurri.jp">remko.popma@azzurri.jp</A>> =
wrote in=20
message <A=20
=
href=3D"news:bame1f$ht6$1@rogue.oti.com">news:bame1f$ht6$1@rogue.oti.com<=
/A>...</DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Ed,</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>I added the bug to =
bugzilla: </FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2><TT><A=20
href=3D"https://bugs.eclipse.org/bugs/show_bug.cgi?id=3D38069"=20
=
target=3D_blank>https://bugs.eclipse.org/bugs/show_bug.cgi?id=3D38069</A>=
<BR></TT></FONT></DIV>
<DIV><FONT size=3D2><TT><FONT face=3D"MS =
Pゴシック ">Enjoy your=20
vacation.</FONT></TT></FONT></DIV>
<DIV><FONT size=3D2><TT></TT></FONT> </DIV>
<DIV><FONT size=3D2><TT><FONT face=3D"MS =
Pゴシック ">Remko</FONT></TT></FONT></DIV>
<DIV><FONT size=3D2><TT> </DIV></TT></FONT>
<BLOCKQUOTE=20
style=3D"BORDER-LEFT: #000000 2px solid; MARGIN-LEFT: 5px; =
MARGIN-RIGHT: 0px; PADDING-LEFT: 5px; PADDING-RIGHT: 0px">
<DIV>"Ed Merks" <<A=20
href=3D"mailto:merks@ca.ibm.com">merks@ca.ibm.com</A>> wrote in =
message <A=20
=
href=3D"news:3ECE9442.AB37EEC3@ca.ibm.com">news:3ECE9442.AB37EEC3@ca.ibm.=
com</A>...</DIV>Remko,=20
<P>Your additional request is a very good one. I've already =
made the=20
other change and don't have time for this one right now; I'm going =
on=20
vaction for two weeks. (Yeah!) I'd suggest opening a bugzilla =
defect=20
with this request. <BR> =20
<P>Remko Popma wrote:=20
<BLOCKQUOTE TYPE=3D"CITE">
<STYLE></STYLE>
<FONT face=3D"?? ?????"><FONT =
size=3D-1>Ed,</FONT></FONT> <FONT=20
face=3D"?? ?????"><FONT size=3D-1>Thanks!</FONT></FONT><FONT=20
face=3D"?? ?????"><FONT size=3D-1>Interesting hack with the inner =
class. I=20
didn't notice the brackets in the GenModel =
code...</FONT></FONT><FONT=20
face=3D"?? ?????"><FONT size=3D-1>An extra constructor that takes =
a=20
classloader would be good, I agree.</FONT></FONT> <FONT=20
face=3D"?? ?????"><FONT size=3D-1>If you are going to change =
JETEmitter, can I=20
make a request?</FONT></FONT><FONT face=3D"?? ?????"><FONT =
size=3D-1>Could you=20
add some API to make it possible to add IClasspathEntries to the =
emitter=20
before initialize is called?</FONT></FONT><FONT face=3D"?? =
?????"><FONT=20
size=3D-1>Currently all classpath entries are hard-coded (JRELIB,=20
EMF_COMMON, EMF_ECORE, EMF_CODEGEN, and=20
EMF_CODEGEN_ECORE),</FONT></FONT><FONT face=3D"?? ?????"><FONT =
size=3D-1>which=20
kind of assumes that the meta model is a =
genModel.</FONT></FONT><FONT=20
face=3D"?? ?????"><FONT size=3D-1>I would like to use my own meta =
model but=20
there is no clean way to add my classes to the classpath=20
now.</FONT></FONT><FONT face=3D"?? ?????"><FONT size=3D-1>An =
addClasspathEntry=20
method would be great.</FONT></FONT> <FONT=20
face=3D"?? ?????"><FONT size=3D-1>(Come to think of it, perhaps =
the EMF=20
classpaths don't really belong in the jet package. If JETEmitter =
has a=20
method</FONT></FONT><FONT face=3D"?? ?????"><FONT size=3D-1>to add =
IClasspathEntries, it might make sense to have a subclass of =
JETEmitter=20
(GenModelEmitter or something, you can probably</FONT></FONT><FONT =
face=3D"?? ?????"><FONT size=3D-1>think of a better name) in the=20
org.eclipse.emf.codegen.ecore.genmodel package that would add all =
the=20
classpath</FONT></FONT><FONT face=3D"?? ?????"><FONT =
size=3D-1>entries needed=20
for EMF code generation. Or have a factory method for creating a=20
JETEmitter instance</FONT></FONT><FONT face=3D"?? ?????"><FONT=20
size=3D-1>(instead of calling "new JETEmitter(getTemplatePath(),=20
templateName) { }") that creates the instance and adds the =
necessary=20
classpath entries.</FONT></FONT><FONT face=3D"?? ?????"><FONT =
size=3D-1>This=20
would remove the last genmodel dependency from the jet=20
package...</FONT></FONT><FONT face=3D"?? ?????"><FONT =
size=3D-1>Hm... Might be=20
a lot of work in the genmodel package. Oh well. Just my 2=20
cents.)</FONT></FONT> <FONT face=3D"?? ?????"><FONT =
size=3D-1>Thanks=20
again for the help.</FONT></FONT><FONT face=3D"?? ?????"><FONT=20
size=3D-1>Remko</FONT></FONT> =20
<BLOCKQUOTE=20
style=3D"BORDER-LEFT: #000000 2px solid; MARGIN-LEFT: 5px; =
MARGIN-RIGHT: 0px; PADDING-LEFT: 5px; PADDING-RIGHT: 0px">"Ed=20
Merks" <<A =
href=3D"mailto:merks@ca.ibm.com">merks@ca.ibm.com</A>>=20
wrote in message <A=20
=
href=3D"news:3ECDFC5E.B7E5E4F4@ca.ibm.com">news:3ECDFC5E.B7E5E4F4@ca.ibm.=
com</A>...Remko,=20
<P>In the JETEmitter there is this line of code:=20
<BLOCKQUOTE>URLClassLoader classLoader =3D new =
URLClassLoader(new URL []=20
{ url },=20
JETEmitter.this.getClass().getClassLoader());</BLOCKQUOTE>Notice =
that=20
it's using the class loader of the JETEmitter class =
itself. =20
Everywhere that we use the JETEmitter in the GenModel code we =
use it=20
like this:=20
<BLOCKQUOTE> interfaceEmitter =3D new =
JETEmitter(getTemplatePath(),=20
interfaceTemplateName) {};</BLOCKQUOTE>Notice that it uses an =
inner=20
class and therefore the code above will pick up the class loader =
that=20
can load GenModel classes. Without the inner classes, the=20
classloader of the JETEmitter itself, i.e., the classloader for =
the=20
org.eclipse.emf.codegen plugin, and it can't see much.=20
<P>Clearly this is very non-obvious, and there isn't even a =
speck of=20
Javadoc. I'm going to change the JETEmitter code so that =
the class=20
loader can be provided as an argument and I'm going to change =
the=20
GenModel to use it like this:=20
<BLOCKQUOTE>interfaceEmitter =3D new =
JETEmitter(getTemplatePath(),=20
interfaceTemplateName, =
getClass().getClassLoader());</BLOCKQUOTE>I think=20
this will make the behavior more obvious. Sorry you had to =
struggle so hard... <BR> =20
<P>Remko Popma wrote:=20
<BLOCKQUOTE TYPE=3D"CITE">Ed,=20
<P>Thanks for your reply. Calling JETEmitter from a plugin =
action=20
(like =
<BR>org.eclipse.emf.codegen.action.CompileTemplateAction) solved=20
<BR>the NullPointerException problem.=20
<P>I'm not sure if it's ok to ask a new question in the same =
thread,=20
but here <BR>goes:=20
<P>From a previous post <BR>(<A=20
=
href=3D" http://www.eclipse.org/newsportal/article.php3?id=3D58&a mp;group=3D=
eclipse.tools.em"> http://www.eclipse.org/newsportal/article.php3?id=3D58&=
amp;group=3Declipse.tools.em</A>=20
<BR>f) I understood that it's possible to pass <BR>my custom =
model=20
(that is, a non-ecore model) to a template. So instead of =
<BR>passing=20
a String argument, I now try to pass a simple bean class =
(extending=20
<BR>Object) to the template.=20
<P>This looks like it should work, but a NoClassDefFoundError =
gets=20
thrown <BR>when JETEmitter.generate() is called. <BR>This is =
where I=20
got stuck... I've added my bean class to the classpath <BR>of =
the=20
.JETEmitters project in several different ways, but it doesn't =
seem=20
<BR>to make a difference.=20
<P>More details follow below. <BR>Any pointers would be =
greatly=20
appreciated.=20
<P>The template looks like this: <BR><%@ jet =
package=3D"hello"=20
imports=3D"main.*" class=3D"HelloWorld" %> <BR><% =
Employee employee=20
=3D (Employee)argument; %> <BR>public class HelloWorld {=20
<BR> public static void main(String[] args) { <BR> =20
System.out.println("Employee name=3D<%=3D =
employee.getName() %>");=20
<BR> } <BR>}=20
<P>And the action that calls it looks like this: =
<BR>JETEmitter emit =3D=20
new JETEmitter(templateURI); <BR>Employee employee =3D new =
Employee();=20
<BR>String result =3D emit.generate(new NullProgressMonitor(), =
new=20
Object[] <BR>{employee}); <BR>System.out.println(result);=20
<P>The first time I got this exception:=20
<BR>org.eclipse.emf.codegen.jet.JETException: Resource=20
/.JETEmitters/runtime <BR>already exists. <BR> at=20
=
org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:383)=20
<BR> at=20
=
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)=20
<BR> at main.Main.run(Main.java:51)=20
<P>This happened only once. <BR>Next, nothing happened when I =
ran my=20
action, until I figured out that the <BR>javajet <BR>template =
was=20
compiled into a HelloWorld.java source file correctly, but the =
<BR>source file could not compile. The HelloWorld.java source =
file is=20
located in <BR>a <BR>project called .JETEmitters that gets =
created by=20
JETEmitter. Adding <BR>Employee to the classpath of the =
..JETEmitters=20
project solved <BR>the compilation problem.=20
<P>Running my emit action again got the exception below, =
<BR>where the=20
cause seems to be a NoClassDefFoundError. =
<BR>---------------------=20
<BR>org.eclipse.emf.codegen.jet.JETException[0]:=20
<BR>java.lang.reflect.InvocationTargetException <BR> at=20
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)=20
<BR> at=20
=
<BR> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.=
java:39=20
<BR>) <BR> at=20
=
<BR> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAcces=
sorImpl=20
<BR>.java:25) <BR> at=20
java.lang.reflect.Method.invoke(Method.java:324) <BR> at=20
=
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:429)=20
<BR> at main.Main.run(Main.java:51) <BR> at=20
=
org.eclipse.ui.internal.PluginAction.runWithEvent(PluginActi on.java:251) =
<BR> at=20
=
<BR> org.eclipse.jface.action.ActionContributionItem.handleWidget Selection=
(Action=20
<BR>ContributionItem.java:456) <BR> at=20
=
<BR> org.eclipse.jface.action.ActionContributionItem.handleWidget Event(Act=
ionCont=20
<BR>ributionItem.java:403) <BR> at=20
=
<BR> org.eclipse.jface.action.ActionContributionItem.access$0(Act ionContri=
butionI=20
<BR>tem.java:397) <BR> at=20
=
<BR> org.eclipse.jface.action.ActionContributionItem$ActionListen er.handle=
Event(A=20
<BR>ctionContributionItem.java:72) <BR> at=20
=
org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java :81)=20
<BR> at =
org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:840)=20
<BR> at=20
=
org.eclipse.swt.widgets.Display.runDeferredEvents(Display.ja va:1838)=20
<BR> at=20
=
org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :1545)=20
<BR> at=20
=
org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:1402)=20
<BR> at=20
org.eclipse.ui.internal.Workbench.run(Workbench.java:1385)=2 0
<BR> at=20
=
<BR> org.eclipse.core.internal.boot.InternalBootLoader.run(Intern alBootLoa=
der.jav=20
<BR>a:845) <BR> at=20
org.eclipse.core.boot.BootLoader.run(BootLoader.java:461) =
<BR> at=20
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)=20
<BR> at=20
=
<BR> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.=
java:39=20
<BR>) <BR> at=20
=
<BR> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAcces=
sorImpl=20
<BR>.java:25) <BR> at=20
java.lang.reflect.Method.invoke(Method.java:324) <BR> at=20
org.eclipse.core.launcher.Main.basicRun(Main.java:291) =
<BR> at=20
org.eclipse.core.launcher.Main.run(Main.java:747) <BR> at =
org.eclipse.core.launcher.Main.main(Main.java:583) <BR>Caused =
by:=20
java.lang.NoClassDefFoundError: main/Employee <BR> at=20
hello.HelloWorld.generate(HelloWorld.java:22) <BR> ... 26 =
more=20
<BR>Unhandled exception caught in event loop. <BR>Reason:=20
<BR>org.eclipse.emf.codegen.jet.JETException:=20
<BR>--------------------------=20
<P>I've tried to change the way the Employee class is added to =
the=20
classpath, <BR>but nothing seems to make a difference. Any =
help would=20
be very welcome.=20
<P>Thanks,=20
<P>Remko Popma=20
<P>"Ed Merks" <merks@ca.ibm.com> wrote in message <BR><A =
=
href=3D"news:3ECB64E5.A16E8DCD@ca.ibm.com">news:3ECB64E5.A16E8DCD@ca.ibm.=
com</A>...=20
<BR>> Remko, <BR>> <BR>> JET is designed to run only =
as a=20
workspace application so you must <BR>mimimally <BR>> run =
it as an=20
Eclipse headless application (so that plugin initialization =
<BR>takes=20
<BR>> places). <BR>> <BR>> <BR>> Remko Popma =
wrote:=20
<BR>> <BR>> > Hi all, <BR>> > <BR>> > =
Could=20
anyone help me with this problem? <BR>> > <BR>> > =
I'm=20
trying to call "generate" on a JETEmitter instance, <BR>> =
> but=20
a NullpointerEx gets thrown in JETEmitter.initialize(). =
<BR>> >=20
<BR>> > This is my code: <BR>> > <BR>> > =
JETEmitter=20
emitter =3D new JETEmitter( <BR>>=20
> &a mp;nbsp; =20
"/sandbox/templates/HelloWorld.javajet"); <BR>> > =
String[] args=20
=3D new String[] {"hi" }; <BR>> > String result =3D=20
emitter.generate(new NullProgressMonitor(), args); <BR>> =
>=20
System.out.println(result); <BR>> > <BR>> > And =
this is=20
the stack trace: <BR>> > <BR>> >=20
java.lang.NullPointerException <BR>> > at=20
=
<BR> org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:169=
)=20
<BR>> > at=20
=
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)=20
<BR>> > at runhello.Main.main(Main.java:24) =
<BR>> >=20
Exception in thread "main" <BR>> > <BR>> > The =
line where=20
the error occurs contains "CodeGenPlugin.getPlugin()", <BR>and =
I=20
<BR>> > think that this returns null, but I don't =
understand=20
why. Is the plugin <BR>> > not activated? I did create =
an=20
interface with @model tags, generated a <BR>> > =
genmodel, and=20
generated an Edit and Editor project from that, so the =
<BR>plugin=20
<BR>> > should be activated... <BR>> > Or am I =
missing=20
something else completely? <BR>> > Should I not use =
JETEmitter=20
this way? <BR>> > <BR>> > Any help would be very =
welcome.=20
<BR>> > Thanks, <BR>> > Remko Popma <BR>> > =
<BR>>=20
<BR> =20
=
------------------------------------------------------------ ------------ =
<BR>>=20
=
> &a mp;nbsp; &a mp;nb=
sp; &nb sp; =20
Name: jetsandbox.gif <BR>> > =20
jetsandbox.gif Type: GIF Image (image/gif) =
<BR>>=20
=
> &a mp;nbsp; &a mp;nb=
sp; =20
Encoding: base64=20
=
<BR>></P></BLOCKQUOTE></BLOCKQUOTE></BLOCKQUOTE> </BLOCKQUOTE></BLOCKQU=
OTE></BODY></HTML>
------=_NextPart_000_016F_01C3222B.F86B3720--
|
|
|
| Re: getting started with JETEmitter [message #377633 is a reply to message #377623] |
Mon, 26 May 2003 12:23   |
|
Originally posted by: remko.popma.azzurri.jp
This is a multi-part message in MIME format.
------=_NextPart_000_01E8_01C323EE.8E7BEA20
Content-Type: multipart/alternative;
boundary="----=_NextPart_001_01E9_01C323EE.8E7BEA20"
------=_NextPart_001_01E9_01C323EE.8E7BEA20
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
I've written a subclass of JETEmitter that allows clients to add classpath
entries to the internal ".JETEmitters" project so that models of any type
(not just genmodel classes) can be used.
I'm posting it here, maybe someone else can use it.
It contains some documentation on how to use JETEmitter.
Remko
"Ed Merks" <merks@ca.ibm.com> wrote in message
news:3ECE9442.AB37EEC3@ca.ibm.com...
Remko,
Your additional request is a very good one. I've already made the other
change and don't have time for this one right now; I'm going on vaction for
two weeks. (Yeah!) I'd suggest opening a bugzilla defect with this request.
Remko Popma wrote:
Ed, Thanks!Interesting hack with the inner class. I didn't notice the
brackets in the GenModel code...An extra constructor that takes a
classloader would be good, I agree. If you are going to change JETEmitter,
can I make a request?Could you add some API to make it possible to add
IClasspathEntries to the emitter before initialize is called?Currently all
classpath entries are hard-coded (JRELIB, EMF_COMMON, EMF_ECORE,
EMF_CODEGEN, and EMF_CODEGEN_ECORE),which kind of assumes that the meta
model is a genModel.I would like to use my own meta model but there is no
clean way to add my classes to the classpath now.An addClasspathEntry method
would be great. (Come to think of it, perhaps the EMF classpaths don't
really belong in the jet package. If JETEmitter has a methodto add
IClasspathEntries, it might make sense to have a subclass of JETEmitter
(GenModelEmitter or something, you can probablythink of a better name) in
the org.eclipse.emf.codegen.ecore.genmodel package that would add all the
classpathentries needed for EMF code generation. Or have a factory method
for creating a JETEmitter instance(instead of calling "new
JETEmitter(getTemplatePath(), templateName) { }") that creates the instance
and adds the necessary classpath entries.This would remove the last genmodel
dependency from the jet package...Hm... Might be a lot of work in the
genmodel package. Oh well. Just my 2 cents.) Thanks again for the help.Remko
"Ed Merks" <merks@ca.ibm.com> wrote in message
news:3ECDFC5E.B7E5E4F4@ca.ibm.com...Remko,
In the JETEmitter there is this line of code:
URLClassLoader classLoader = new URLClassLoader(new URL [] { url },
JETEmitter.this.getClass().getClassLoader());
Notice that it's using the class loader of the JETEmitter class
itself. Everywhere that we use the JETEmitter in the GenModel code we use
it like this:
interfaceEmitter = new JETEmitter(getTemplatePath(),
interfaceTemplateName) {};
Notice that it uses an inner class and therefore the code above will
pick up the class loader that can load GenModel classes. Without the inner
classes, the classloader of the JETEmitter itself, i.e., the classloader for
the org.eclipse.emf.codegen plugin, and it can't see much.
Clearly this is very non-obvious, and there isn't even a speck of
Javadoc. I'm going to change the JETEmitter code so that the class loader
can be provided as an argument and I'm going to change the GenModel to use
it like this:
interfaceEmitter = new JETEmitter(getTemplatePath(),
interfaceTemplateName, getClass().getClassLoader());
I think this will make the behavior more obvious. Sorry you had to
struggle so hard...
Remko Popma wrote:
Ed,
Thanks for your reply. Calling JETEmitter from a plugin action (like
org.eclipse.emf.codegen.action.CompileTemplateAction) solved
the NullPointerException problem.
I'm not sure if it's ok to ask a new question in the same thread,
but here
goes:
From a previous post
( http://www.eclipse.org/newsportal/article.php3?id=58&gro up=eclipse.tools.em
f) I understood that it's possible to pass
my custom model (that is, a non-ecore model) to a template. So
instead of
passing a String argument, I now try to pass a simple bean class
(extending
Object) to the template.
This looks like it should work, but a NoClassDefFoundError gets
thrown
when JETEmitter.generate() is called.
This is where I got stuck... I've added my bean class to the
classpath
of the .JETEmitters project in several different ways, but it
doesn't seem
to make a difference.
More details follow below.
Any pointers would be greatly appreciated.
The template looks like this:
<%@ jet package="hello" imports="main.*" class="HelloWorld" %>
<% Employee employee = (Employee)argument; %>
public class HelloWorld
public static void main(String[] args)
System.out.println("Employee name=<%= employee.getName() %>");
}
}
And the action that calls it looks like this:
JETEmitter emit = new JETEmitter(templateURI);
Employee employee = new Employee();
String result = emit.generate(new NullProgressMonitor(), new
Object[]
{employee});
System.out.println(result);
The first time I got this exception:
org.eclipse.emf.codegen.jet.JETException: Resource
/.JETEmitters/runtime
already exists.
at
org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:383)
at
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)
at main.Main.run(Main.java:51)
This happened only once.
Next, nothing happened when I ran my action, until I figured out
that the
javajet
template was compiled into a HelloWorld.java source file correctly,
but the
source file could not compile. The HelloWorld.java source file is
located in
a
project called .JETEmitters that gets created by JETEmitter. Adding
Employee to the classpath of the .JETEmitters project solved
the compilation problem.
Running my emit action again got the exception below,
where the cause seems to be a NoClassDefFoundError.
---------------------
org.eclipse.emf.codegen.jet.JETException[0]:
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.java:39
)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorImpl
.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:429)
at main.Main.run(Main.java:51)
at
org.eclipse.ui.internal.PluginAction.runWithEvent(PluginActi on.java:251)
at
org.eclipse.jface.action.ActionContributionItem.handleWidget Selection(Action
ContributionItem.java:456)
at
org.eclipse.jface.action.ActionContributionItem.handleWidget Event(ActionCont
ributionItem.java:403)
at
org.eclipse.jface.action.ActionContributionItem.access$0(Act ionContributionI
tem.java:397)
at
org.eclipse.jface.action.ActionContributionItem$ActionListen er.handleEvent(A
ctionContributionItem.java:72)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java :81)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:840)
at
org.eclipse.swt.widgets.Display.runDeferredEvents(Display.ja va:1838)
at
org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :1545)
at
org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:1402)
at org.eclipse.ui.internal.Workbench.run(Workbench.java:1385)
at
org.eclipse.core.internal.boot.InternalBootLoader.run(Intern alBootLoader.jav
a:845)
at org.eclipse.core.boot.BootLoader.run(BootLoader.java:461)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.java:39
)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorImpl
.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.eclipse.core.launcher.Main.basicRun(Main.java:291)
at org.eclipse.core.launcher.Main.run(Main.java:747)
at org.eclipse.core.launcher.Main.main(Main.java:583)
Caused by: java.lang.NoClassDefFoundError: main/Employee
at hello.HelloWorld.generate(HelloWorld.java:22)
... 26 more
Unhandled exception caught in event loop.
Reason:
org.eclipse.emf.codegen.jet.JETException:
--------------------------
I've tried to change the way the Employee class is added to the
classpath,
but nothing seems to make a difference. Any help would be very
welcome.
Thanks,
Remko Popma
"Ed Merks" <merks@ca.ibm.com> wrote in message
news:3ECB64E5.A16E8DCD@ca.ibm.com...
> Remko,
>
> JET is designed to run only as a workspace application so you must
mimimally
> run it as an Eclipse headless application (so that plugin
initialization
takes
> places).
>
>
> Remko Popma wrote:
>
> > Hi all,
> >
> > Could anyone help me with this problem?
> >
> > I'm trying to call "generate" on a JETEmitter instance,
> > but a NullpointerEx gets thrown in JETEmitter.initialize().
> >
> > This is my code:
> >
> > JETEmitter emitter = new
Emitter(
> > "/sandbox/templates/HelloWorld.javajet");
> > String[] args = new String[] {"hi" };
> > String result = emitter.generate(new NullProgressMonitor(), args);
> > System.out.println(result);
> >
> > And this is the stack trace:
> >
> > java.lang.NullPointerException
> > at
org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:169)
> > at
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)
> > at runhello.Main.main(Main.java:24)
> > Exception in thread "main"
> >
> > The line where the error occurs contains
"CodeGenPlugin.getPlugin()",
and I
> > think that this returns null, but I don't understand why. Is the
plugin
> > not activated? I did create an interface with @model tags,
generated a
> > genmodel, and generated an Edit and Editor project from that, so
the
plugin
> > should be activated...
> > Or am I missing something else completely?
> > Should I not use JETEmitter this way?
> >
> > Any help would be very welcome.
> > Thanks,
> > Remko Popma
> >
>
------------------------------------------------------------ ------
------
> > Name: jetsandbox.gif
> > jetsandbox.gif Type: GIF Image (image/gif)
> > Encoding: base64
>
------=_NextPart_001_01E9_01C323EE.8E7BEA20
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content=3D"text/html; charset=3Diso-8859-1" =
http-equiv=3DContent-Type>
<META content=3D"MSHTML 5.00.2920.0" name=3DGENERATOR></HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>I've written a =
subclass of JETEmitter that=20
allows clients to add classpath entries to the internal ".JETEmitters"=20
</FONT><FONT face=3D"MS =
Pゴシック " size=3D2>project so that =
models of any type (not just=20
genmodel classes) can be used.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>I'm posting it here, =
maybe someone else can=20
use it.</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>It contains some =
documentation on how to use=20
JETEmitter.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Remko</FONT></DIV>
<DIV> </DIV>
<BLOCKQUOTE=20
style=3D"BORDER-LEFT: #000000 2px solid; MARGIN-LEFT: 5px; MARGIN-RIGHT: =
0px; PADDING-LEFT: 5px; PADDING-RIGHT: 0px">
<DIV>"Ed Merks" <<A =
href=3D"mailto:merks@ca.ibm.com">merks@ca.ibm.com</A>>=20
wrote in message <A=20
=
href=3D"news:3ECE9442.AB37EEC3@ca.ibm.com">news:3ECE9442.AB37EEC3@ca.ibm.=
com</A>...</DIV>Remko,=20
<P>Your additional request is a very good one. I've already made =
the=20
other change and don't have time for this one right now; I'm going on =
vaction=20
for two weeks. (Yeah!) I'd suggest opening a bugzilla defect =
with this=20
request. <BR> =20
<P>Remko Popma wrote:=20
<BLOCKQUOTE TYPE=3D"CITE">
<STYLE></STYLE>
<FONT face=3D"?? ?????"><FONT size=3D-1>Ed,</FONT></FONT> <FONT =
face=3D"?? ?????"><FONT size=3D-1>Thanks!</FONT></FONT><FONT=20
face=3D"?? ?????"><FONT size=3D-1>Interesting hack with the inner =
class. I=20
didn't notice the brackets in the GenModel =
code...</FONT></FONT><FONT=20
face=3D"?? ?????"><FONT size=3D-1>An extra constructor that takes a =
classloader=20
would be good, I agree.</FONT></FONT> <FONT face=3D"?? =
?????"><FONT=20
size=3D-1>If you are going to change JETEmitter, can I make a=20
request?</FONT></FONT><FONT face=3D"?? ?????"><FONT size=3D-1>Could =
you add some=20
API to make it possible to add IClasspathEntries to the emitter =
before=20
initialize is called?</FONT></FONT><FONT face=3D"?? ?????"><FONT=20
size=3D-1>Currently all classpath entries are hard-coded (JRELIB, =
EMF_COMMON,=20
EMF_ECORE, EMF_CODEGEN, and EMF_CODEGEN_ECORE),</FONT></FONT><FONT=20
face=3D"?? ?????"><FONT size=3D-1>which kind of assumes that the =
meta model is a=20
genModel.</FONT></FONT><FONT face=3D"?? ?????"><FONT size=3D-1>I =
would like to=20
use my own meta model but there is no clean way to add my classes to =
the=20
classpath now.</FONT></FONT><FONT face=3D"?? ?????"><FONT =
size=3D-1>An=20
addClasspathEntry method would be =
great.</FONT></FONT> <FONT=20
face=3D"?? ?????"><FONT size=3D-1>(Come to think of it, perhaps the =
EMF=20
classpaths don't really belong in the jet package. If JETEmitter has =
a=20
method</FONT></FONT><FONT face=3D"?? ?????"><FONT size=3D-1>to add=20
IClasspathEntries, it might make sense to have a subclass of =
JETEmitter=20
(GenModelEmitter or something, you can probably</FONT></FONT><FONT=20
face=3D"?? ?????"><FONT size=3D-1>think of a better name) in the=20
org.eclipse.emf.codegen.ecore.genmodel package that would add all =
the=20
classpath</FONT></FONT><FONT face=3D"?? ?????"><FONT =
size=3D-1>entries needed=20
for EMF code generation. Or have a factory method for creating a =
JETEmitter=20
instance</FONT></FONT><FONT face=3D"?? ?????"><FONT =
size=3D-1>(instead of=20
calling "new JETEmitter(getTemplatePath(), templateName) { }") that =
creates=20
the instance and adds the necessary classpath =
entries.</FONT></FONT><FONT=20
face=3D"?? ?????"><FONT size=3D-1>This would remove the last =
genmodel dependency=20
from the jet package...</FONT></FONT><FONT face=3D"?? ?????"><FONT=20
size=3D-1>Hm... Might be a lot of work in the genmodel package. Oh =
well. Just=20
my 2 cents.)</FONT></FONT> <FONT face=3D"?? ?????"><FONT =
size=3D-1>Thanks=20
again for the help.</FONT></FONT><FONT face=3D"?? ?????"><FONT=20
size=3D-1>Remko</FONT></FONT> =20
<BLOCKQUOTE=20
style=3D"BORDER-LEFT: #000000 2px solid; MARGIN-LEFT: 5px; =
MARGIN-RIGHT: 0px; PADDING-LEFT: 5px; PADDING-RIGHT: 0px">"Ed=20
Merks" <<A =
href=3D"mailto:merks@ca.ibm.com">merks@ca.ibm.com</A>>=20
wrote in message <A=20
=
href=3D"news:3ECDFC5E.B7E5E4F4@ca.ibm.com">news:3ECDFC5E.B7E5E4F4@ca.ibm.=
com</A>...Remko,=20
<P>In the JETEmitter there is this line of code:=20
<BLOCKQUOTE>URLClassLoader classLoader =3D new URLClassLoader(new =
URL [] {=20
url }, =
JETEmitter.this.getClass().getClassLoader());</BLOCKQUOTE>Notice=20
that it's using the class loader of the JETEmitter class =
itself. =20
Everywhere that we use the JETEmitter in the GenModel code we use =
it like=20
this:=20
<BLOCKQUOTE> interfaceEmitter =3D new =
JETEmitter(getTemplatePath(),=20
interfaceTemplateName) {};</BLOCKQUOTE>Notice that it uses an =
inner class=20
and therefore the code above will pick up the class loader that =
can load=20
GenModel classes. Without the inner classes, the classloader =
of the=20
JETEmitter itself, i.e., the classloader for the =
org.eclipse.emf.codegen=20
plugin, and it can't see much.=20
<P>Clearly this is very non-obvious, and there isn't even a speck =
of=20
Javadoc. I'm going to change the JETEmitter code so that the =
class=20
loader can be provided as an argument and I'm going to change the =
GenModel=20
to use it like this:=20
<BLOCKQUOTE>interfaceEmitter =3D new JETEmitter(getTemplatePath(), =
interfaceTemplateName, =
getClass().getClassLoader());</BLOCKQUOTE>I think=20
this will make the behavior more obvious. Sorry you had to =
struggle=20
so hard... <BR> =20
<P>Remko Popma wrote:=20
<BLOCKQUOTE TYPE=3D"CITE">Ed,=20
<P>Thanks for your reply. Calling JETEmitter from a plugin =
action (like=20
<BR>org.eclipse.emf.codegen.action.CompileTemplateAction) solved =
<BR>the=20
NullPointerException problem.=20
<P>I'm not sure if it's ok to ask a new question in the same =
thread, but=20
here <BR>goes:=20
<P>From a previous post <BR>(<A=20
=
href=3D" http://www.eclipse.org/newsportal/article.php3?id=3D58&a mp;group=3D=
eclipse.tools.em"> http://www.eclipse.org/newsportal/article.php3?id=3D58&=
amp;group=3Declipse.tools.em</A>=20
<BR>f) I understood that it's possible to pass <BR>my custom =
model (that=20
is, a non-ecore model) to a template. So instead of <BR>passing =
a String=20
argument, I now try to pass a simple bean class (extending =
<BR>Object)=20
to the template.=20
<P>This looks like it should work, but a NoClassDefFoundError =
gets=20
thrown <BR>when JETEmitter.generate() is called. <BR>This is =
where I got=20
stuck... I've added my bean class to the classpath <BR>of the=20
.JETEmitters project in several different ways, but it doesn't =
seem=20
<BR>to make a difference.=20
<P>More details follow below. <BR>Any pointers would be greatly=20
appreciated.=20
<P>The template looks like this: <BR><%@ jet =
package=3D"hello"=20
imports=3D"main.*" class=3D"HelloWorld" %> <BR><% Employee =
employee =3D=20
(Employee)argument; %> <BR>public class HelloWorld { =
<BR> public=20
static void main(String[] args) { <BR> =20
System.out.println("Employee name=3D<%=3D employee.getName() =
%>");=20
<BR> } <BR>}=20
<P>And the action that calls it looks like this: <BR>JETEmitter =
emit =3D=20
new JETEmitter(templateURI); <BR>Employee employee =3D new =
Employee();=20
<BR>String result =3D emit.generate(new NullProgressMonitor(), =
new=20
Object[] <BR>{employee}); <BR>System.out.println(result);=20
<P>The first time I got this exception:=20
<BR>org.eclipse.emf.codegen.jet.JETException: Resource=20
/.JETEmitters/runtime <BR>already exists. <BR> at=20
=
org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:383)=20
<BR> at=20
=
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)=20
<BR> at main.Main.run(Main.java:51)=20
<P>This happened only once. <BR>Next, nothing happened when I =
ran my=20
action, until I figured out that the <BR>javajet <BR>template =
was=20
compiled into a HelloWorld.java source file correctly, but the=20
<BR>source file could not compile. The HelloWorld.java source =
file is=20
located in <BR>a <BR>project called .JETEmitters that gets =
created by=20
JETEmitter. Adding <BR>Employee to the classpath of the =
..JETEmitters=20
project solved <BR>the compilation problem.=20
<P>Running my emit action again got the exception below, =
<BR>where the=20
cause seems to be a NoClassDefFoundError. =
<BR>---------------------=20
<BR>org.eclipse.emf.codegen.jet.JETException[0]:=20
<BR>java.lang.reflect.InvocationTargetException <BR> at=20
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) =
<BR> at=20
=
<BR> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.=
java:39=20
<BR>) <BR> at=20
=
<BR> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAcces=
sorImpl=20
<BR>.java:25) <BR> at=20
java.lang.reflect.Method.invoke(Method.java:324) <BR> at=20
=
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:429)=20
<BR> at main.Main.run(Main.java:51) <BR> at=20
=
org.eclipse.ui.internal.PluginAction.runWithEvent(PluginActi on.java:251) =
<BR> at=20
=
<BR> org.eclipse.jface.action.ActionContributionItem.handleWidget Selection=
(Action=20
<BR>ContributionItem.java:456) <BR> at=20
=
<BR> org.eclipse.jface.action.ActionContributionItem.handleWidget Event(Act=
ionCont=20
<BR>ributionItem.java:403) <BR> at=20
=
<BR> org.eclipse.jface.action.ActionContributionItem.access$0(Act ionContri=
butionI=20
<BR>tem.java:397) <BR> at=20
=
<BR> org.eclipse.jface.action.ActionContributionItem$ActionListen er.handle=
Event(A=20
<BR>ctionContributionItem.java:72) <BR> at=20
org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java :81) =
<BR> at =
org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:840)=20
<BR> at=20
=
org.eclipse.swt.widgets.Display.runDeferredEvents(Display.ja va:1838)=20
<BR> at=20
=
org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :1545)=20
<BR> at=20
=
org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:1402)=20
<BR> at =
org.eclipse.ui.internal.Workbench.run(Workbench.java:1385)=2 0
<BR> at=20
=
<BR> org.eclipse.core.internal.boot.InternalBootLoader.run(Intern alBootLoa=
der.jav=20
<BR>a:845) <BR> at=20
org.eclipse.core.boot.BootLoader.run(BootLoader.java:461) =
<BR> at=20
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) =
<BR> at=20
=
<BR> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.=
java:39=20
<BR>) <BR> at=20
=
<BR> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAcces=
sorImpl=20
<BR>.java:25) <BR> at=20
java.lang.reflect.Method.invoke(Method.java:324) <BR> at=20
org.eclipse.core.launcher.Main.basicRun(Main.java:291) =
<BR> at=20
org.eclipse.core.launcher.Main.run(Main.java:747) <BR> at=20
org.eclipse.core.launcher.Main.main(Main.java:583) <BR>Caused =
by:=20
java.lang.NoClassDefFoundError: main/Employee <BR> at=20
hello.HelloWorld.generate(HelloWorld.java:22) <BR> ... 26 =
more=20
<BR>Unhandled exception caught in event loop. <BR>Reason:=20
<BR>org.eclipse.emf.codegen.jet.JETException:=20
<BR>--------------------------=20
<P>I've tried to change the way the Employee class is added to =
the=20
classpath, <BR>but nothing seems to make a difference. Any help =
would be=20
very welcome.=20
<P>Thanks,=20
<P>Remko Popma=20
<P>"Ed Merks" <merks@ca.ibm.com> wrote in message <BR><A=20
=
href=3D"news:3ECB64E5.A16E8DCD@ca.ibm.com">news:3ECB64E5.A16E8DCD@ca.ibm.=
com</A>...=20
<BR>> Remko, <BR>> <BR>> JET is designed to run only as =
a=20
workspace application so you must <BR>mimimally <BR>> run it =
as an=20
Eclipse headless application (so that plugin initialization =
<BR>takes=20
<BR>> places). <BR>> <BR>> <BR>> Remko Popma wrote: =
<BR>>=20
<BR>> > Hi all, <BR>> > <BR>> > Could anyone =
help me=20
with this problem? <BR>> > <BR>> > I'm trying to =
call=20
"generate" on a JETEmitter instance, <BR>> > but a =
NullpointerEx=20
gets thrown in JETEmitter.initialize(). <BR>> > <BR>> =
> This=20
is my code: <BR>> > <BR>> > JETEmitter emitter =3D =
new=20
JETEmitter( <BR>>=20
> &a mp;nbsp; =20
"/sandbox/templates/HelloWorld.javajet"); <BR>> > String[] =
args =3D=20
new String[] {"hi" }; <BR>> > String result =3D =
emitter.generate(new=20
NullProgressMonitor(), args); <BR>> > =
System.out.println(result);=20
<BR>> > <BR>> > And this is the stack trace: =
<BR>> >=20
<BR>> > java.lang.NullPointerException <BR>> > =
at=20
=
<BR> org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:169=
)=20
<BR>> > at=20
=
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)=20
<BR>> > at runhello.Main.main(Main.java:24) <BR>> =
>=20
Exception in thread "main" <BR>> > <BR>> > The line =
where=20
the error occurs contains "CodeGenPlugin.getPlugin()", <BR>and I =
<BR>> > think that this returns null, but I don't =
understand why.=20
Is the plugin <BR>> > not activated? I did create an =
interface=20
with @model tags, generated a <BR>> > genmodel, and =
generated an=20
Edit and Editor project from that, so the <BR>plugin <BR>> =
>=20
should be activated... <BR>> > Or am I missing something =
else=20
completely? <BR>> > Should I not use JETEmitter this way? =
<BR>>=20
> <BR>> > Any help would be very welcome. <BR>> > =
Thanks,=20
<BR>> > Remko Popma <BR>> > <BR>> <BR> =20
=
------------------------------------------------------------ ------------ =
<BR>>=20
=
> &a mp;nbsp; &a mp;nb=
sp; &nb sp; =20
Name: jetsandbox.gif <BR>> > =20
jetsandbox.gif Type: GIF Image (image/gif) =
<BR>>=20
=
> &a mp;nbsp; &a mp;nb=
sp; =20
Encoding: base64=20
<BR>></P></BLOCKQUOTE></BLOCKQUOTE></BLOCKQUOTE> </BLOCKQUOTE></BODY></=
HTML>
------=_NextPart_001_01E9_01C323EE.8E7BEA20--
------=_NextPart_000_01E8_01C323EE.8E7BEA20
Content-Type: application/octet-stream;
name="MyJETEmitter.java"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="MyJETEmitter.java"
package main;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ILibrary;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IPluginDescriptor;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.emf.codegen.jet.JETEmitter;
import org.eclipse.emf.codegen.jet.JETException;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
/**
* Extends JETEmitter to allow adding classpath entries.
* <p>
* The <code>JETEmitter</code> class combines the functionality
* of the various classes in the =
<code>org.eclipse.emf.codegen.jet</code>
* package and is the entry point for clients who want=20
* to use JET functionality.
* <p>
* Example usage:
* <pre>
* String project =3D "/myproject";
* String fullPath =3D project + "/templates/mytemplate.javajet";
* String templateURI =3D "platform:/resource" + fullPath;
*=20
* // Note that you MUST use a subclass of JETEmitter that is
* // defined in your project because of classloader issues.=20
* JETEmitter jetEmitter =3D new JETEmitter(templateURI) { }; // create =
anonymous subclass
*=20
* // If your template is passed a non-genmodel argument,
* // you need to add the JAR file containing the argument classes
* // to the classpath of the project where the templates are compiled.
* jetEmitter.addVariable("MY_CLASSPATH_VARIABLE", "myplugin.id");
*=20
* IProgressMonitor monitor =3D new NullProgressMonitor();
* Object myModel =3D // your meta-model instance
* String result =3D jetEmitter.generate(monitor, new Object[] =
{myModel});
* </pre>
* <p>
* Note that JET is designed to run only as a workspace application,
* and classes in this package will not function if plugin =
initialization
* has not taken place.
* You can only use JETEmitter from a plugin, or=20
* mimimally when run as an Eclipse headless application.
* <p>
* Internally, this class will create a java project called
* ".JETEmitters" in the workspace. JET templates are compiled
* to java source files in this project. Once java source files
* are created, Eclipse JDT facilities are used to compile these
* files to class files. It is the responsibility of the
* client code to ensure that all model classes referenced
* in the template are available to the JDT compiler
* by adding classpath variables to this JETEmitter.
*=20
* @author Remko Popma
* @version $Revision: 1.1 $ ($Date: 2003/05/26 07:41:10 $)
*/
public class MyJETEmitter extends JETEmitter
{
private List mClasspathEntries =3D new ArrayList();
/**
* Constructs a JETEmitter with the specified template URI.
* The specified uri should point to a valid=20
* JET template location when resolved
* with <code>Platform.resolve(new URL(templateURI))</code>
* or <code>new URL("file:/" + templateURI)</code>.
*=20
* @param templateURI the uri to pass to the
* <code>JETCompiler</code> constructor
* @see =
org.eclipse.emf.codegen.jet.JETCompiler#JETCompiler(java.lan g.String)
*/
public MyJETEmitter(String templateURI)
{
super(templateURI);
}
/**
* Constructs a JETEmitter with the specified template uri
* path and relative template uri.
* The result of appending the specified relative template uri
* to one of the uris in the specified template uri path array
* should point to a valid JET template location when resolved
* with <code>Platform.resolve(new URL(templateURI))</code>
* or <code>new URL("file:/" + templateURI)</code>.
*=20
* @param templateURIPath an array of uris the =
<code>JETCompiler</code>
* may try to find the relative template uri under
* @param relativeTemplateURI part of the template uri relative
* to one of the specified templateURIPaths
* @see =
org.eclipse.emf.codegen.jet.JETCompiler#JETCompiler(java.lan g.String[], =
java.lang.String)
*/
public MyJETEmitter(String[] templateURIPath, String =
relativeTemplateURI)
{
super(templateURIPath, relativeTemplateURI);
}
/**
* Registers the specified classpath variable in the workspace,
* bound to the first runtime library JAR file in the list
* of runtime libraries of the specified plugin.
* When the {@link =
JETEmitter#generate(org.eclipse.core.runtime.IProgressMonito r, =
java.lang.Object[]) generate}
* method or the {@link =
JETEmitter#initialize(org.eclipse.core.runtime.IProgressMoni tor) =
initialize}
* method is called,
* the specified classpath variable will be added to the
* classpath of the internal ".JETEmitters" project=20
* where emitted JET templates are compiled.
* <p>
* This method must be called <b>before</b>
* {@link =
JETEmitter#initialize(org.eclipse.core.runtime.IProgressMoni tor)}
* or {@link =
JETEmitter#generate(org.eclipse.core.runtime.IProgressMonito r, =
java.lang.Object[]) generate}
* are called.
* <p>
* The specified plugin ID must be the ID of an existing plugin.
* The referenced plugin must have at least one=20
* runtime library JAR file in its plugin descriptor.
* If the plugin descriptor's list of
* runtime libraries contains more than one JAR file, the=20
* classpath variable will be bound to the <b>first</b>
* library in the list.
* <p>
* =20
* @param variableName name of the classpath variable
* @param pluginID the ID of the plugin whose runtime library
* to bind to the specified classpath variable
* @throws NullPointerException if no plugin with the=20
* specified plugin ID could be found
* @throws JETException if the runtime library path
* points to a directory instead of a JAR file,
* if an error occurred while registering the
* classpath variable in the workspace, or
* if the runtime library path
* could not be combined with the plugin's install
* directory to form a valid URL
*/
public void addVariable(String variableName, String pluginID) throws =
JETException
{
IPluginDescriptor descriptor =3D =
Platform.getPlugin(pluginID).getDescriptor();
ILibrary[] libraries =3D descriptor.getRuntimeLibraries();
for (int i =3D 0; i < libraries.length; ++i)
{
if (libraries[i].getType().equals(ILibrary.CODE))
{
URL url =3D null;
try
{
url =3D new URL(descriptor.getInstallURL(), =
libraries[i].getPath().toString());
} catch (MalformedURLException e)
{
throw new JETException(e);
}
try
{
IPath path =3D new Path(Platform.asLocalURL(url).getFile());
if (!path.equals(JavaCore.getClasspathVariable(variableName)))
{
JavaCore.setClasspathVariable(variableName, path, null);
}
} catch (JavaModelException e)
{
throw new JETException(e);
} catch (IOException e)
{
throw new JETException(
"Could not resolve URL " + url + " as a JAR file. Library =
path must point to an existing JAR file.",
e);
}
break;
}
}
IClasspathEntry entry =3D JavaCore.newVariableEntry(new =
Path(variableName), null, null);
addClasspathEntry(entry);
}
/**
* Adds the specified <code>IClasspathEntry</code> to the list
* of entries to add to the classpath of the internal ".JETEmitters" =
project=20
* where emitted JET templates are compiled.
* <p>
* This method must be called <b>before</b>
* {@link =
JETEmitter#initialize(org.eclipse.core.runtime.IProgressMoni tor)}
* or {@link =
JETEmitter#generate(org.eclipse.core.runtime.IProgressMonito r, =
java.lang.Object[]) generate}
* are called.
*=20
* @param entry the IClasspathEntry to add to the classpath
* of the internal ".JETEmitters" project
*/
public void addClasspathEntry(IClasspathEntry entry)
{
mClasspathEntries.add(entry);
}
/**
* Overrides the superclass implementation to first
* add all added <code>IClasspathEntry</code> objects
* to the classpath of the ".JETEmitters" project.
* After adding the classpath entries, the super implementation
* of this method is invoked.
* <p>
* If the ".JETEmitters" project does not exist, the super
* implementation of this method is invoked twice:=20
* once to create the project, and finally after the
* classpath entries are added.
*/
public void initialize(IProgressMonitor progressMonitor) throws =
JETException
{
final IWorkspace workspace =3D ResourcesPlugin.getWorkspace();
final IProject project =3D =
workspace.getRoot().getProject(".JETEmitters");
if (!project.exists())
{
super.initialize(progressMonitor);
}
try
{
project.open(new SubProgressMonitor(progressMonitor, 5));
IJavaProject javaProject =3D JavaCore.create(project);
IClasspathEntry[] existing =3D javaProject.getRawClasspath();
IClasspathEntry[] newEntries =3D addMissing(existing);
if (newEntries.length > existing.length)
{
javaProject.setRawClasspath(newEntries, new =
SubProgressMonitor(progressMonitor, 1));
}
} catch (CoreException e)
{
throw new JETException(e);
}
super.initialize(progressMonitor);
}
/**
* Returns an array containing the union of the specified array
* and the <code>IClasspathEntry</code> objects in the list
* of added <code>IClasspathEntry</code> objects.
*=20
* @param existing array with existing classpath entries
* @return an array containing the union of the specified array
* and the <code>IClasspathEntry</code> objects in the list
* of added entries
*/
private IClasspathEntry[] addMissing(IClasspathEntry[] existing)
{
if (mClasspathEntries.isEmpty())
{
return existing;
}
ArrayList result =3D new ArrayList(mClasspathEntries.size() + =
existing.length);
result.addAll(Arrays.asList(existing));
for (Iterator i =3D mClasspathEntries.iterator(); i.hasNext();)
{
IClasspathEntry entry =3D (IClasspathEntry) i.next();
if (!result.contains(entry))
{
result.add(entry);
}
}
return (IClasspathEntry[]) result.toArray(new =
IClasspathEntry[result.size()]);
}
}
------=_NextPart_000_01E8_01C323EE.8E7BEA20--
|
|
|
| Re: getting started with JETEmitter [message #377635 is a reply to message #377633] |
Mon, 26 May 2003 14:43   |
Knut Wannheden Messages: 283 Registered: July 2009 |
Senior Member |
|
|
This is a multi-part message in MIME format.
------=_NextPart_000_004E_01C323C7.82EE5F70
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Great!
I've been using JET in a standalone application for some time now. But =
I'm not using dynamic templates, so I precompile the templates inside =
Eclipse first and then use them in the standalone application, where no =
JET runtime is required anymore. I actually also wrote a simple Ant =
task to compile the JET templates outside Eclipse. I then compile the =
generated source using Ant's usual <javac/> and can load the class with =
reflection. But it never occured to me that maybe JETEmitter could be =
used. I'll have to investigate that.
Note on the Ant task: To get it to work I need the jars of the following =
plugins on the classpath: org.eclipse.core.boot, =
org.eclipse.core.runtime, org.eclipse.core.resources, =
org.eclipse.jdt.core, and org.eclipse.emf.codegen. This is rather a =
lot... But if anyone is interested I'd be happy to send the Ant task.
--
knut
"Remko Popma" <remko.popma@azzurri.jp> wrote in message =
news:batf3b$bi1$1@rogue.oti.com...
I've written a subclass of JETEmitter that allows clients to add =
classpath entries to the internal ".JETEmitters" project so that models =
of any type (not just genmodel classes) can be used.
I'm posting it here, maybe someone else can use it.
It contains some documentation on how to use JETEmitter.
Remko
"Ed Merks" <merks@ca.ibm.com> wrote in message =
news:3ECE9442.AB37EEC3@ca.ibm.com...
Remko,=20
Your additional request is a very good one. I've already made the =
other change and don't have time for this one right now; I'm going on =
vaction for two weeks. (Yeah!) I'd suggest opening a bugzilla defect =
with this request.=20
=20
Remko Popma wrote:=20
Ed, Thanks!Interesting hack with the inner class. I didn't notice =
the brackets in the GenModel code...An extra constructor that takes a =
classloader would be good, I agree. If you are going to change =
JETEmitter, can I make a request?Could you add some API to make it =
possible to add IClasspathEntries to the emitter before initialize is =
called?Currently all classpath entries are hard-coded (JRELIB, =
EMF_COMMON, EMF_ECORE, EMF_CODEGEN, and EMF_CODEGEN_ECORE),which kind of =
assumes that the meta model is a genModel.I would like to use my own =
meta model but there is no clean way to add my classes to the classpath =
now.An addClasspathEntry method would be great. (Come to think of it, =
perhaps the EMF classpaths don't really belong in the jet package. If =
JETEmitter has a methodto add IClasspathEntries, it might make sense to =
have a subclass of JETEmitter (GenModelEmitter or something, you can =
probablythink of a better name) in the =
org.eclipse.emf.codegen.ecore.genmodel package that would add all the =
classpathentries needed for EMF code generation. Or have a factory =
method for creating a JETEmitter instance(instead of calling "new =
JETEmitter(getTemplatePath(), templateName) { }") that creates the =
instance and adds the necessary classpath entries.This would remove the =
last genmodel dependency from the jet package...Hm... Might be a lot of =
work in the genmodel package. Oh well. Just my 2 cents.) Thanks again =
for the help.Remko =20
"Ed Merks" <merks@ca.ibm.com> wrote in message =
news:3ECDFC5E.B7E5E4F4@ca.ibm.com...Remko,=20
In the JETEmitter there is this line of code:=20
URLClassLoader classLoader =3D new URLClassLoader(new URL [] { =
url }, JETEmitter.this.getClass().getClassLoader());
Notice that it's using the class loader of the JETEmitter class =
itself. Everywhere that we use the JETEmitter in the GenModel code we =
use it like this:=20
interfaceEmitter =3D new JETEmitter(getTemplatePath(), =
interfaceTemplateName) {};
Notice that it uses an inner class and therefore the code above =
will pick up the class loader that can load GenModel classes. Without =
the inner classes, the classloader of the JETEmitter itself, i.e., the =
classloader for the org.eclipse.emf.codegen plugin, and it can't see =
much.=20
Clearly this is very non-obvious, and there isn't even a speck =
of Javadoc. I'm going to change the JETEmitter code so that the class =
loader can be provided as an argument and I'm going to change the =
GenModel to use it like this:=20
interfaceEmitter =3D new JETEmitter(getTemplatePath(), =
interfaceTemplateName, getClass().getClassLoader());
I think this will make the behavior more obvious. Sorry you had =
to struggle so hard...=20
=20
Remko Popma wrote:=20
Ed,=20
Thanks for your reply. Calling JETEmitter from a plugin action =
(like=20
org.eclipse.emf.codegen.action.CompileTemplateAction) solved=20
the NullPointerException problem.=20
I'm not sure if it's ok to ask a new question in the same =
thread, but here=20
goes:=20
From a previous post=20
=
( http://www.eclipse.org/newsportal/article.php3?id=3D58&g roup=3Declipse.t=
ools.em=20
f) I understood that it's possible to pass=20
my custom model (that is, a non-ecore model) to a template. So =
instead of=20
passing a String argument, I now try to pass a simple bean =
class (extending=20
Object) to the template.=20
This looks like it should work, but a NoClassDefFoundError =
gets thrown=20
when JETEmitter.generate() is called.=20
This is where I got stuck... I've added my bean class to the =
classpath=20
of the .JETEmitters project in several different ways, but it =
doesn't seem=20
to make a difference.=20
More details follow below.=20
Any pointers would be greatly appreciated.=20
The template looks like this:=20
<%@ jet package=3D"hello" imports=3D"main.*" =
class=3D"HelloWorld" %>=20
<% Employee employee =3D (Employee)argument; %>=20
public class HelloWorld {=20
public static void main(String[] args) {=20
System.out.println("Employee name=3D<%=3D employee.getName() =
%>");=20
}=20
}=20
And the action that calls it looks like this:=20
JETEmitter emit =3D new JETEmitter(templateURI);=20
Employee employee =3D new Employee();=20
String result =3D emit.generate(new NullProgressMonitor(), new =
Object[]=20
{employee});=20
System.out.println(result);=20
The first time I got this exception:=20
org.eclipse.emf.codegen.jet.JETException: Resource =
/.JETEmitters/runtime=20
already exists.=20
at =
org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:383)=20
at =
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)=20
at main.Main.run(Main.java:51)=20
This happened only once.=20
Next, nothing happened when I ran my action, until I figured =
out that the=20
javajet=20
template was compiled into a HelloWorld.java source file =
correctly, but the=20
source file could not compile. The HelloWorld.java source file =
is located in=20
a=20
project called .JETEmitters that gets created by JETEmitter. =
Adding=20
Employee to the classpath of the .JETEmitters project solved=20
the compilation problem.=20
Running my emit action again got the exception below,=20
where the cause seems to be a NoClassDefFoundError.=20
---------------------=20
org.eclipse.emf.codegen.jet.JETException[0]:=20
java.lang.reflect.InvocationTargetException=20
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native =
Method)=20
at=20
=
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.java=
:39=20
)=20
at=20
=
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorI=
mpl=20
.java:25)=20
at java.lang.reflect.Method.invoke(Method.java:324)=20
at =
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:429)=20
at main.Main.run(Main.java:51)=20
at =
org.eclipse.ui.internal.PluginAction.runWithEvent(PluginActi on.java:251) =
at=20
=
org.eclipse.jface.action.ActionContributionItem.handleWidget Selection(Act=
ion=20
ContributionItem.java:456)=20
at=20
=
org.eclipse.jface.action.ActionContributionItem.handleWidget Event(ActionC=
ont=20
ributionItem.java:403)=20
at=20
=
org.eclipse.jface.action.ActionContributionItem.access$0(Act ionContributi=
onI=20
tem.java:397)=20
at=20
=
org.eclipse.jface.action.ActionContributionItem$ActionListen er.handleEven=
t(A=20
ctionContributionItem.java:72)=20
at =
org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java :81)=20
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:840)=20
at =
org.eclipse.swt.widgets.Display.runDeferredEvents(Display.ja va:1838)=20
at =
org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :1545)=20
at =
org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:1402)=20
at org.eclipse.ui.internal.Workbench.run(Workbench.java:1385) =
at=20
=
org.eclipse.core.internal.boot.InternalBootLoader.run(Intern alBootLoader.=
jav=20
a:845)=20
at org.eclipse.core.boot.BootLoader.run(BootLoader.java:461)=20
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native =
Method)=20
at=20
=
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.java=
:39=20
)=20
at=20
=
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorI=
mpl=20
.java:25)=20
at java.lang.reflect.Method.invoke(Method.java:324)=20
at org.eclipse.core.launcher.Main.basicRun(Main.java:291)=20
at org.eclipse.core.launcher.Main.run(Main.java:747)=20
at org.eclipse.core.launcher.Main.main(Main.java:583)=20
Caused by: java.lang.NoClassDefFoundError: main/Employee=20
at hello.HelloWorld.generate(HelloWorld.java:22)=20
... 26 more=20
Unhandled exception caught in event loop.=20
Reason:=20
org.eclipse.emf.codegen.jet.JETException:=20
--------------------------=20
I've tried to change the way the Employee class is added to =
the classpath,=20
but nothing seems to make a difference. Any help would be very =
welcome.=20
Thanks,=20
Remko Popma=20
"Ed Merks" <merks@ca.ibm.com> wrote in message=20
news:3ECB64E5.A16E8DCD@ca.ibm.com...=20
> Remko,=20
>=20
> JET is designed to run only as a workspace application so =
you must=20
mimimally=20
> run it as an Eclipse headless application (so that plugin =
initialization=20
takes=20
> places).=20
>=20
>=20
> Remko Popma wrote:=20
>=20
> > Hi all,=20
> >=20
> > Could anyone help me with this problem?=20
> >=20
> > I'm trying to call "generate" on a JETEmitter instance,=20
> > but a NullpointerEx gets thrown in =
JETEmitter.initialize().=20
> >=20
> > This is my code:=20
> >=20
> > JETEmitter emitter =3D new JETEmitter(=20
> > "/sandbox/templates/HelloWorld.javajet");=20
> > String[] args =3D new String[] {"hi" };=20
> > String result =3D emitter.generate(new =
NullProgressMonitor(), args);=20
> > System.out.println(result);=20
> >=20
> > And this is the stack trace:=20
> >=20
> > java.lang.NullPointerException=20
> > at=20
=
org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:169)=20
> > at =
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)=20
> > at runhello.Main.main(Main.java:24)=20
> > Exception in thread "main"=20
> >=20
> > The line where the error occurs contains =
"CodeGenPlugin.getPlugin()",=20
and I=20
> > think that this returns null, but I don't understand why. =
Is the plugin=20
> > not activated? I did create an interface with @model tags, =
generated a=20
> > genmodel, and generated an Edit and Editor project from =
that, so the=20
plugin=20
> > should be activated...=20
> > Or am I missing something else completely?=20
> > Should I not use JETEmitter this way?=20
> >=20
> > Any help would be very welcome.=20
> > Thanks,=20
> > Remko Popma=20
> >=20
>=20
=
------------------------------------------------------------ ------------ =
> > Name: jetsandbox.gif=20
> > jetsandbox.gif Type: GIF Image (image/gif)=20
> > Encoding: base64=20
>
------=_NextPart_000_004E_01C323C7.82EE5F70
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.2800.1170" name=3DGENERATOR></HEAD>
<BODY bgColor=3D#ffffff>
<DIV>
<DIV><FONT face=3DArial size=3D2>Great!</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>I've been using JET in a standalone =
application for=20
some time now. But I'm not using dynamic templates, so I =
precompile the=20
templates inside Eclipse first and then use them in the standalone =
application,=20
where no JET runtime is required anymore. I actually also wrote a =
simple=20
Ant task to compile the JET templates outside Eclipse. I then =
compile the=20
generated source using Ant's usual <javac/> and can load the class =
with=20
reflection. But it never occured to me that maybe JETEmitter could =
be=20
used. I'll have to investigate that.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Note on the Ant task: To get it to work =
I need the=20
jars of the following plugins on the classpath: org.eclipse.core.boot,=20
org.eclipse.core.runtime, org.eclipse.core.resources, =
org.eclipse.jdt.core, and=20
org.eclipse.emf.codegen. This is rather a lot... But if =
anyone is=20
interested I'd be happy to send the Ant task.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>--</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>knut</FONT></DIV></DIV>
<BLOCKQUOTE dir=3Dltr=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
<DIV>"Remko Popma" <<A=20
href=3D"mailto:remko.popma@azzurri.jp">remko.popma@azzurri.jp</A>> =
wrote in=20
message <A=20
=
href=3D"news:batf3b$bi1$1@rogue.oti.com">news:batf3b$bi1$1@rogue.oti.com<=
/A>...</DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>I've written a =
subclass of JETEmitter that=20
allows clients to add classpath entries to the internal ".JETEmitters" =
</FONT><FONT face=3D"MS =
Pゴシック " size=3D2>project so that =
models of any type (not=20
just genmodel classes) can be used.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>I'm posting it here, =
maybe someone else can=20
use it.</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>It contains some =
documentation on how to use=20
JETEmitter.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Remko</FONT></DIV>
<DIV> </DIV>
<BLOCKQUOTE=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
<DIV>"Ed Merks" <<A=20
href=3D"mailto:merks@ca.ibm.com">merks@ca.ibm.com</A>> wrote in =
message <A=20
=
href=3D"news:3ECE9442.AB37EEC3@ca.ibm.com">news:3ECE9442.AB37EEC3@ca.ibm.=
com</A>...</DIV>Remko,=20
<P>Your additional request is a very good one. I've already =
made the=20
other change and don't have time for this one right now; I'm going =
on=20
vaction for two weeks. (Yeah!) I'd suggest opening a bugzilla =
defect=20
with this request. <BR> =20
<P>Remko Popma wrote:=20
<BLOCKQUOTE TYPE=3D"CITE">
<STYLE></STYLE>
<FONT face=3D"?? ?????"><FONT =
size=3D-1>Ed,</FONT></FONT> <FONT=20
face=3D"?? ?????"><FONT size=3D-1>Thanks!</FONT></FONT><FONT=20
face=3D"?? ?????"><FONT size=3D-1>Interesting hack with the inner =
class. I=20
didn't notice the brackets in the GenModel =
code...</FONT></FONT><FONT=20
face=3D"?? ?????"><FONT size=3D-1>An extra constructor that takes =
a=20
classloader would be good, I agree.</FONT></FONT> <FONT=20
face=3D"?? ?????"><FONT size=3D-1>If you are going to change =
JETEmitter, can I=20
make a request?</FONT></FONT><FONT face=3D"?? ?????"><FONT =
size=3D-1>Could you=20
add some API to make it possible to add IClasspathEntries to the =
emitter=20
before initialize is called?</FONT></FONT><FONT face=3D"?? =
?????"><FONT=20
size=3D-1>Currently all classpath entries are hard-coded (JRELIB,=20
EMF_COMMON, EMF_ECORE, EMF_CODEGEN, and=20
EMF_CODEGEN_ECORE),</FONT></FONT><FONT face=3D"?? ?????"><FONT =
size=3D-1>which=20
kind of assumes that the meta model is a =
genModel.</FONT></FONT><FONT=20
face=3D"?? ?????"><FONT size=3D-1>I would like to use my own meta =
model but=20
there is no clean way to add my classes to the classpath=20
now.</FONT></FONT><FONT face=3D"?? ?????"><FONT size=3D-1>An =
addClasspathEntry=20
method would be great.</FONT></FONT> <FONT=20
face=3D"?? ?????"><FONT size=3D-1>(Come to think of it, perhaps =
the EMF=20
classpaths don't really belong in the jet package. If JETEmitter =
has a=20
method</FONT></FONT><FONT face=3D"?? ?????"><FONT size=3D-1>to add =
IClasspathEntries, it might make sense to have a subclass of =
JETEmitter=20
(GenModelEmitter or something, you can probably</FONT></FONT><FONT =
face=3D"?? ?????"><FONT size=3D-1>think of a better name) in the=20
org.eclipse.emf.codegen.ecore.genmodel package that would add all =
the=20
classpath</FONT></FONT><FONT face=3D"?? ?????"><FONT =
size=3D-1>entries needed=20
for EMF code generation. Or have a factory method for creating a=20
JETEmitter instance</FONT></FONT><FONT face=3D"?? ?????"><FONT=20
size=3D-1>(instead of calling "new JETEmitter(getTemplatePath(),=20
templateName) { }") that creates the instance and adds the =
necessary=20
classpath entries.</FONT></FONT><FONT face=3D"?? ?????"><FONT =
size=3D-1>This=20
would remove the last genmodel dependency from the jet=20
package...</FONT></FONT><FONT face=3D"?? ?????"><FONT =
size=3D-1>Hm... Might be=20
a lot of work in the genmodel package. Oh well. Just my 2=20
cents.)</FONT></FONT> <FONT face=3D"?? ?????"><FONT =
size=3D-1>Thanks=20
again for the help.</FONT></FONT><FONT face=3D"?? ?????"><FONT=20
size=3D-1>Remko</FONT></FONT> =20
<BLOCKQUOTE=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">"Ed=20
Merks" <<A =
href=3D"mailto:merks@ca.ibm.com">merks@ca.ibm.com</A>>=20
wrote in message <A=20
=
href=3D"news:3ECDFC5E.B7E5E4F4@ca.ibm.com">news:3ECDFC5E.B7E5E4F4@ca.ibm.=
com</A>...Remko,=20
<P>In the JETEmitter there is this line of code:=20
<BLOCKQUOTE>URLClassLoader classLoader =3D new =
URLClassLoader(new URL []=20
{ url },=20
JETEmitter.this.getClass().getClassLoader());</BLOCKQUOTE>Notice =
that=20
it's using the class loader of the JETEmitter class =
itself. =20
Everywhere that we use the JETEmitter in the GenModel code we =
use it=20
like this:=20
<BLOCKQUOTE> interfaceEmitter =3D new =
JETEmitter(getTemplatePath(),=20
interfaceTemplateName) {};</BLOCKQUOTE>Notice that it uses an =
inner=20
class and therefore the code above will pick up the class loader =
that=20
can load GenModel classes. Without the inner classes, the=20
classloader of the JETEmitter itself, i.e., the classloader for =
the=20
org.eclipse.emf.codegen plugin, and it can't see much.=20
<P>Clearly this is very non-obvious, and there isn't even a =
speck of=20
Javadoc. I'm going to change the JETEmitter code so that =
the class=20
loader can be provided as an argument and I'm going to change =
the=20
GenModel to use it like this:=20
<BLOCKQUOTE>interfaceEmitter =3D new =
JETEmitter(getTemplatePath(),=20
interfaceTemplateName, =
getClass().getClassLoader());</BLOCKQUOTE>I think=20
this will make the behavior more obvious. Sorry you had to =
struggle so hard... <BR> =20
<P>Remko Popma wrote:=20
<BLOCKQUOTE TYPE=3D"CITE">Ed,=20
<P>Thanks for your reply. Calling JETEmitter from a plugin =
action=20
(like =
<BR>org.eclipse.emf.codegen.action.CompileTemplateAction) solved=20
<BR>the NullPointerException problem.=20
<P>I'm not sure if it's ok to ask a new question in the same =
thread,=20
but here <BR>goes:=20
<P>From a previous post <BR>(<A=20
=
href=3D" http://www.eclipse.org/newsportal/article.php3?id=3D58&a mp;group=3D=
eclipse.tools.em"> http://www.eclipse.org/newsportal/article.php3?id=3D58&=
amp;group=3Declipse.tools.em</A>=20
<BR>f) I understood that it's possible to pass <BR>my custom =
model=20
(that is, a non-ecore model) to a template. So instead of =
<BR>passing=20
a String argument, I now try to pass a simple bean class =
(extending=20
<BR>Object) to the template.=20
<P>This looks like it should work, but a NoClassDefFoundError =
gets=20
thrown <BR>when JETEmitter.generate() is called. <BR>This is =
where I=20
got stuck... I've added my bean class to the classpath <BR>of =
the=20
.JETEmitters project in several different ways, but it doesn't =
seem=20
<BR>to make a difference.=20
<P>More details follow below. <BR>Any pointers would be =
greatly=20
appreciated.=20
<P>The template looks like this: <BR><%@ jet =
package=3D"hello"=20
imports=3D"main.*" class=3D"HelloWorld" %> <BR><% =
Employee employee=20
=3D (Employee)argument; %> <BR>public class HelloWorld {=20
<BR> public static void main(String[] args) { <BR> =20
System.out.println("Employee name=3D<%=3D =
employee.getName() %>");=20
<BR> } <BR>}=20
<P>And the action that calls it looks like this: =
<BR>JETEmitter emit =3D=20
new JETEmitter(templateURI); <BR>Employee employee =3D new =
Employee();=20
<BR>String result =3D emit.generate(new NullProgressMonitor(), =
new=20
Object[] <BR>{employee}); <BR>System.out.println(result);=20
<P>The first time I got this exception:=20
<BR>org.eclipse.emf.codegen.jet.JETException: Resource=20
/.JETEmitters/runtime <BR>already exists. <BR> at=20
=
org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:383)=20
<BR> at=20
=
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)=20
<BR> at main.Main.run(Main.java:51)=20
<P>This happened only once. <BR>Next, nothing happened when I =
ran my=20
action, until I figured out that the <BR>javajet <BR>template =
was=20
compiled into a HelloWorld.java source file correctly, but the =
<BR>source file could not compile. The HelloWorld.java source =
file is=20
located in <BR>a <BR>project called .JETEmitters that gets =
created by=20
JETEmitter. Adding <BR>Employee to the classpath of the =
..JETEmitters=20
project solved <BR>the compilation problem.=20
<P>Running my emit action again got the exception below, =
<BR>where the=20
cause seems to be a NoClassDefFoundError. =
<BR>---------------------=20
<BR>org.eclipse.emf.codegen.jet.JETException[0]:=20
<BR>java.lang.reflect.InvocationTargetException <BR> at=20
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)=20
<BR> at=20
=
<BR> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.=
java:39=20
<BR>) <BR> at=20
=
<BR> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAcces=
sorImpl=20
<BR>.java:25) <BR> at=20
java.lang.reflect.Method.invoke(Method.java:324) <BR> at=20
=
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:429)=20
<BR> at main.Main.run(Main.java:51) <BR> at=20
=
org.eclipse.ui.internal.PluginAction.runWithEvent(PluginActi on.java:251) =
<BR> at=20
=
<BR> org.eclipse.jface.action.ActionContributionItem.handleWidget Selection=
(Action=20
<BR>ContributionItem.java:456) <BR> at=20
=
<BR> org.eclipse.jface.action.ActionContributionItem.handleWidget Event(Act=
ionCont=20
<BR>ributionItem.java:403) <BR> at=20
=
<BR> org.eclipse.jface.action.ActionContributionItem.access$0(Act ionContri=
butionI=20
<BR>tem.java:397) <BR> at=20
=
<BR> org.eclipse.jface.action.ActionContributionItem$ActionListen er.handle=
Event(A=20
<BR>ctionContributionItem.java:72) <BR> at=20
=
org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java :81)=20
<BR> at =
org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:840)=20
<BR> at=20
=
org.eclipse.swt.widgets.Display.runDeferredEvents(Display.ja va:1838)=20
<BR> at=20
=
org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :1545)=20
<BR> at=20
=
org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:1402)=20
<BR> at=20
org.eclipse.ui.internal.Workbench.run(Workbench.java:1385)=2 0
<BR> at=20
=
<BR> org.eclipse.core.internal.boot.InternalBootLoader.run(Intern alBootLoa=
der.jav=20
<BR>a:845) <BR> at=20
org.eclipse.core.boot.BootLoader.run(BootLoader.java:461) =
<BR> at=20
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)=20
<BR> at=20
=
<BR> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.=
java:39=20
<BR>) <BR> at=20
=
<BR> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAcces=
sorImpl=20
<BR>.java:25) <BR> at=20
java.lang.reflect.Method.invoke(Method.java:324) <BR> at=20
org.eclipse.core.launcher.Main.basicRun(Main.java:291) =
<BR> at=20
org.eclipse.core.launcher.Main.run(Main.java:747) <BR> at =
org.eclipse.core.launcher.Main.main(Main.java:583) <BR>Caused =
by:=20
java.lang.NoClassDefFoundError: main/Employee <BR> at=20
hello.HelloWorld.generate(HelloWorld.java:22) <BR> ... 26 =
more=20
<BR>Unhandled exception caught in event loop. <BR>Reason:=20
<BR>org.eclipse.emf.codegen.jet.JETException:=20
<BR>--------------------------=20
<P>I've tried to change the way the Employee class is added to =
the=20
classpath, <BR>but nothing seems to make a difference. Any =
help would=20
be very welcome.=20
<P>Thanks,=20
<P>Remko Popma=20
<P>"Ed Merks" <merks@ca.ibm.com> wrote in message <BR><A =
=
href=3D"news:3ECB64E5.A16E8DCD@ca.ibm.com">news:3ECB64E5.A16E8DCD@ca.ibm.=
com</A>...=20
<BR>> Remko, <BR>> <BR>> JET is designed to run only =
as a=20
workspace application so you must <BR>mimimally <BR>> run =
it as an=20
Eclipse headless application (so that plugin initialization =
<BR>takes=20
<BR>> places). <BR>> <BR>> <BR>> Remko Popma =
wrote:=20
<BR>> <BR>> > Hi all, <BR>> > <BR>> > =
Could=20
anyone help me with this problem? <BR>> > <BR>> > =
I'm=20
trying to call "generate" on a JETEmitter instance, <BR>> =
> but=20
a NullpointerEx gets thrown in JETEmitter.initialize(). =
<BR>> >=20
<BR>> > This is my code: <BR>> > <BR>> > =
JETEmitter=20
emitter =3D new JETEmitter( <BR>>=20
> &a mp;nbsp; =20
"/sandbox/templates/HelloWorld.javajet"); <BR>> > =
String[] args=20
=3D new String[] {"hi" }; <BR>> > String result =3D=20
emitter.generate(new NullProgressMonitor(), args); <BR>> =
>=20
System.out.println(result); <BR>> > <BR>> > And =
this is=20
the stack trace: <BR>> > <BR>> >=20
java.lang.NullPointerException <BR>> > at=20
=
<BR> org.eclipse.emf.codegen.jet.JETEmitter.initialize(JETEmitter .java:169=
)=20
<BR>> > at=20
=
org.eclipse.emf.codegen.jet.JETEmitter.generate(JETEmitter.j ava:421)=20
<BR>> > at runhello.Main.main(Main.java:24) =
<BR>> >=20
Exception in thread "main" <BR>> > <BR>> > The =
line where=20
the error occurs contains "CodeGenPlugin.getPlugin()", <BR>and =
I=20
<BR>> > think that this returns null, but I don't =
understand=20
why. Is the plugin <BR>> > not activated? I did create =
an=20
interface with @model tags, generated a <BR>> > =
genmodel, and=20
generated an Edit and Editor project from that, so the =
<BR>plugin=20
<BR>> > should be activated... <BR>> > Or am I =
missing=20
something else completely? <BR>> > Should I not use =
JETEmitter=20
this way? <BR>> > <BR>> > Any help would be very =
welcome.=20
<BR>> > Thanks, <BR>> > Remko Popma <BR>> > =
<BR>>=20
<BR> =20
=
------------------------------------------------------------ ------------ =
<BR>>=20
=
> &a mp;nbsp; &a mp;nb=
sp; &nb sp; =20
Name: jetsandbox.gif <BR>> > =20
jetsandbox.gif Type: GIF Image (image/gif) =
<BR>>=20
=
> &a mp;nbsp; &a mp;nb=
sp; =20
Encoding: base64=20
=
<BR>></P></BLOCKQUOTE></BLOCKQUOTE></BLOCKQUOTE> </BLOCKQUOTE></BLOCKQU=
OTE></BODY></HTML>
------=_NextPart_000_004E_01C323C7.82EE5F70--
|
|
|
| Re: getting started with JETEmitter [message #377637 is a reply to message #377635] |
Mon, 26 May 2003 20:25   |
|
Originally posted by: remko.popma.azzurri.jp
This is a multi-part message in MIME format.
------=_NextPart_000_020D_01C32431.E1CF6A10
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Knut,
I'm definitely interested. Can you post it here or send it to me by email?
Thanks.
Remko
"Knut Wannheden" <knut.wannheden@paranor.ch> wrote in message
news:batn96$hf6$1@rogue.oti.com...
Great!
I've been using JET in a standalone application for some time now. But
I'm not using dynamic templates, so I precompile the templates inside
Eclipse first and then use them in the standalone application, where no JET
runtime is required anymore. I actually also wrote a simple Ant task to
compile the JET templates outside Eclipse. I then compile the generated
source using Ant's usual <javac/> and can load the class with reflection.
But it never occured to me that maybe JETEmitter could be used. I'll have
to investigate that.
Note on the Ant task: To get it to work I need the jars of the following
plugins on the classpath: org.eclipse.core.boot, org.eclipse.core.runtime,
org.eclipse.core.resources, org.eclipse.jdt.core, and
org.eclipse.emf.codegen. This is rather a lot... But if anyone is
interested I'd be happy to send the Ant task.
--
knut
------=_NextPart_000_020D_01C32431.E1CF6A10
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content=3D"text/html; charset=3Diso-8859-1" =
http-equiv=3DContent-Type>
<META content=3D"MSHTML 5.00.2920.0" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Knut,</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>I'm definitely =
interested. Can you post it=20
here or send it to me by email?</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Thanks.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Remko</FONT></DIV>
<DIV> </DIV>
<BLOCKQUOTE dir=3Dltr=20
style=3D"BORDER-LEFT: #000000 2px solid; MARGIN-LEFT: 5px; MARGIN-RIGHT: =
0px; PADDING-LEFT: 5px; PADDING-RIGHT: 0px">
<DIV>"Knut Wannheden" <<A=20
=
href=3D"mailto:knut.wannheden@paranor.ch">knut.wannheden@paranor.ch</A>&g=
t;=20
wrote in message <A=20
=
href=3D"news:batn96$hf6$1@rogue.oti.com">news:batn96$hf6$1@rogue.oti.com<=
/A>...</DIV>
<DIV>
<DIV><FONT face=3DArial size=3D2>Great!</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>I've been using JET in a standalone =
application=20
for some time now. But I'm not using dynamic templates, so I =
precompile=20
the templates inside Eclipse first and then use them in the standalone =
application, where no JET runtime is required anymore. I =
actually also=20
wrote a simple Ant task to compile the JET templates outside =
Eclipse. I=20
then compile the generated source using Ant's usual <javac/> and =
can=20
load the class with reflection. But it never occured to me that =
maybe=20
JETEmitter could be used. I'll have to investigate =
that.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Note on the Ant task: To get it to =
work I need=20
the jars of the following plugins on the classpath: =
org.eclipse.core.boot,=20
org.eclipse.core.runtime, org.eclipse.core.resources, =
org.eclipse.jdt.core,=20
and org.eclipse.emf.codegen. This is rather a lot... But =
if anyone=20
is interested I'd be happy to send the Ant task.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>--</FONT></DIV>
<DIV><FONT face=3DArial =
size=3D2>knut</FONT></DIV></DIV></BLOCKQUOTE></BODY></HTML >
------=_NextPart_000_020D_01C32431.E1CF6A10--
|
|
|
| Re: getting started with JETEmitter [message #377646 is a reply to message #377637] |
Wed, 28 May 2003 09:54   |
Knut Wannheden Messages: 283 Registered: July 2009 |
Senior Member |
|
|
This is a multi-part message in MIME format.
------=_NextPart_000_000E_01C32531.6DBCC9A0
Content-Type: multipart/alternative;
boundary="----=_NextPart_001_000F_01C32531.6DBE5040"
------=_NextPart_001_000F_01C32531.6DBE5040
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Remko,
Here you go (source and jar)!
Some notes:
a.. The task both runs the JET compiler and Ant's <javac/>, so the =
final result is a .class file. But it's easy to change so it only =
performs the first step.
b.. The task only handles a single template at the time. An obvious =
and simple improvment would be to make the task handle nested =
<fileset/>s.
c.. In the <taskdef/> you have to specify the classpath to include =
both this task as well as the jars of the plugins I mentioned in the =
earlier mail.
d.. The task supports the "class" attribute (FQCN) which overloads the =
JET directives "class" and "package" in the template. It can also be =
used if the JET directive is missing altogether. I added this attribute =
because sometimes I want to specify the class to generate outside the =
template. (This attribute of course doesn't make any sense if the task =
is enhanced to work with whole <fileset/>s.)
Here's a simple Ant buildfile (the taskdef classpath assumes you have =
Eclipse 2.1 and EMF 1.1.0):
<project default=3D"jetc">
<property name=3D"eclipse.plugins.dir" =
location=3D"C:/Products/eclipse-2.1/plugins"/>
<taskdef name=3D"jetc" =
classname=3D"ch.paranor.epla.structure.JETCTask">
<classpath>
<pathelement location=3D"jetc-task.jar"/>
<fileset dir=3D"${eclipse.plugins.dir}">
<include name=3D"org.eclipse.core.boot_2.1.0/boot.jar"/>
<include name=3D"org.eclipse.core.resources_2.1.0/resources.jar"/>
<include name=3D"org.eclipse.core.runtime_2.1.0/runtime.jar"/>
<include =
name=3D"org.eclipse.emf.codegen_1.1.0/runtime/codegen.jar"/ >
<include name=3D"org.eclipse.jdt.core_2.1.0/jdtcore.jar"/>
</fileset>
</classpath>
</taskdef>
<target name=3D"jetc">
<jetc template=3D"test.xmljet" class=3D"com.foo.Test" =
destdir=3D"."/>
</target>
</project>
Hope you can work with this! And be sure to notify me of any =
improvements you make! :-)
--
knut
"Remko Popma" <remko.popma@azzurri.jp> wrote in message =
news:baubb1$tj7$1@rogue.oti.com...
Knut,
I'm definitely interested. Can you post it here or send it to me by =
email?
Thanks.
Remko
"Knut Wannheden" <knut.wannheden@paranor.ch> wrote in message =
news:batn96$hf6$1@rogue.oti.com...
Great!
I've been using JET in a standalone application for some time now. =
But I'm not using dynamic templates, so I precompile the templates =
inside Eclipse first and then use them in the standalone application, =
where no JET runtime is required anymore. I actually also wrote a =
simple Ant task to compile the JET templates outside Eclipse. I then =
compile the generated source using Ant's usual <javac/> and can load the =
class with reflection. But it never occured to me that maybe JETEmitter =
could be used. I'll have to investigate that.
Note on the Ant task: To get it to work I need the jars of the =
following plugins on the classpath: org.eclipse.core.boot, =
org.eclipse.core.runtime, org.eclipse.core.resources, =
org.eclipse.jdt.core, and org.eclipse.emf.codegen. This is rather a =
lot... But if anyone is interested I'd be happy to send the Ant task.
--
knut
------=_NextPart_001_000F_01C32531.6DBE5040
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.2800.1170" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3DArial size=3D2>Remko,</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Here you go (source and =
jar)!</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Some notes:</FONT></DIV>
<UL>
<LI><FONT face=3DArial size=3D2>The task both runs the JET compiler =
and Ant's=20
<javac/>, so the final result is a .class file. But it's =
easy to=20
change so it only performs the first step.</FONT></LI>
<LI><FONT face=3DArial size=3D2>The task only handles a single =
template at the=20
time. An obvious and simple improvment would be to make the task=20
handle nested <fileset/>s.</FONT></LI>
<LI><FONT face=3DArial size=3D2>In the <taskdef/> you have to =
specify the=20
classpath to include both this task as well as the jars of the plugins =
I=20
mentioned in the earlier mail.</FONT></LI>
<LI><FONT face=3DArial size=3D2>The task supports the "class" =
attribute (FQCN)=20
which overloads the JET directives "class" and "package" in the =
template. It=20
can also be used if the JET directive is missing altogether. I added =
this=20
attribute because sometimes I want to specify the class to generate =
outside=20
the template. (This attribute of course doesn't make any sense =
if the=20
task is enhanced to work with whole =
<fileset/>s.)</FONT></LI></UL>
<DIV><FONT face=3DArial size=3D2>Here's a simple Ant buildfile (the =
taskdef=20
classpath assumes you have Eclipse 2.1 and EMF 1.1.0):</FONT></DIV>
<BLOCKQUOTE dir=3Dltr style=3D"MARGIN-RIGHT: 0px">
<DIV><FONT face=3D"Courier New" size=3D2><project=20
default=3D"jetc"></FONT></DIV>
<DIV><FONT face=3D"Courier New"></FONT> </DIV>
<DIV><FONT face=3D"Courier New" size=3D2> <property=20
name=3D"eclipse.plugins.dir"=20
location=3D"C:/Products/eclipse-2.1/plugins"/></FONT ></DIV>
<DIV><FONT face=3D"Courier New"></FONT> </DIV>
<DIV><FONT face=3D"Courier New" size=3D2> <taskdef =
name=3D"jetc"=20
classname=3D"ch.paranor.epla.structure.JETCTask"><BR > =20
<classpath><BR> <pathelement=20
location=3D"jetc-task.jar"/><BR> <fileset=20
dir=3D"${eclipse.plugins.dir}"><BR> <include=20
name=3D"org.eclipse.core.boot_2.1.0/boot.jar"/><BR > =
<include=20
=
name=3D"org.eclipse.core.resources_2.1.0/resources.jar"/> <BR> &nb=
sp;=20
<include=20
=
name=3D"org.eclipse.core.runtime_2.1.0/runtime.jar"/> <BR> =
<include=20
=
name=3D"org.eclipse.emf.codegen_1.1.0/runtime/codegen.jar"/> <BR> =
=20
<include =
name=3D"org.eclipse.jdt.core_2.1.0/jdtcore.jar"/><BR > =20
=
</fileset><BR> </classpath> <BR> </taskdef></F=
ONT></DIV>
<DIV><FONT face=3D"Courier New"></FONT> </DIV>
<DIV><FONT face=3D"Courier New" size=3D2> <target=20
name=3D"jetc"><BR> <jetc template=3D"test.xmljet" =
class=3D"com.foo.Test"=20
destdir=3D"."/><BR> </target> </FONT></DIV>
<DIV><FONT face=3D"Courier New"></FONT> </DIV>
<DIV dir=3Dltr><FONT face=3D"Courier New"=20
size=3D2></project></FONT></DIV></BLOCKQUOTE >
<DIV dir=3Dltr><FONT face=3DArial size=3D2>Hope you can work with =
this! And be=20
sure to notify me of any improvements you make! :-)</FONT></DIV>
<DIV dir=3Dltr><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV dir=3Dltr><FONT face=3DArial size=3D2>--</FONT></DIV>
<DIV dir=3Dltr><FONT face=3DArial size=3D2>knut</FONT></DIV>
<BLOCKQUOTE dir=3Dltr=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
<DIV>"Remko Popma" <<A=20
href=3D"mailto:remko.popma@azzurri.jp">remko.popma@azzurri.jp</A>> =
wrote in=20
message <A=20
=
href=3D"news:baubb1$tj7$1@rogue.oti.com">news:baubb1$tj7$1@rogue.oti.com<=
/A>...</DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Knut,</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>I'm definitely =
interested. Can you post it=20
here or send it to me by email?</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Thanks.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Remko</FONT></DIV>
<DIV> </DIV>
<BLOCKQUOTE dir=3Dltr=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
<DIV>"Knut Wannheden" <<A=20
=
href=3D"mailto:knut.wannheden@paranor.ch">knut.wannheden@paranor.ch</A>&g=
t;=20
wrote in message <A=20
=
href=3D"news:batn96$hf6$1@rogue.oti.com">news:batn96$hf6$1@rogue.oti.com<=
/A>...</DIV>
<DIV>
<DIV><FONT face=3DArial size=3D2>Great!</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>I've been using JET in a standalone =
application=20
for some time now. But I'm not using dynamic templates, so I=20
precompile the templates inside Eclipse first and then use them in =
the=20
standalone application, where no JET runtime is required =
anymore. I=20
actually also wrote a simple Ant task to compile the JET templates =
outside=20
Eclipse. I then compile the generated source using Ant's usual =
<javac/> and can load the class with reflection. But it =
never=20
occured to me that maybe JETEmitter could be used. I'll have =
to=20
investigate that.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Note on the Ant task: To get it to =
work I need=20
the jars of the following plugins on the classpath: =
org.eclipse.core.boot,=20
org.eclipse.core.runtime, org.eclipse.core.resources, =
org.eclipse.jdt.core,=20
and org.eclipse.emf.codegen. This is rather a lot... But =
if=20
anyone is interested I'd be happy to send the Ant task.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>--</FONT></DIV>
<DIV><FONT face=3DArial=20
size=3D2>knut</FONT></DIV></DIV></BLOCKQUOTE></BLOCKQUOTE ></BODY></HTML>
------=_NextPart_001_000F_01C32531.6DBE5040--
------=_NextPart_000_000E_01C32531.6DBCC9A0
Content-Type: application/octet-stream;
name="jetc-task.jar"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="jetc-task.jar"
UEsDBBQACAAIABZ+vC4AAAAAAAAAAAAAAAAJAAQATUVUQS1JTkYv/soAAAMA UEsHCAAAAAACAAAA
AAAAAFBLAwQUAAgACAAWfrwuAAAAAAAAAAAAAAAAFAAAAE1FVEEtSU5GL01B TklGRVNULk1G803M
y0xLLS7RDUstKs7Mz7NSMNQz4OVyLkpNLElN0XWqBAmY6BnGGxgpaASX5in4 ZiYX5RdXFpek5hYr
eOYl62nycvFyAQBQSwcIIIjsVEcAAABHAAAAUEsDBAoAAAAAAKJ7vC4AAAAA AAAAAAAAAAADAAAA
Y2gvUEsDBAoAAAAAAKJ7vC4AAAAAAAAAAAAAAAALAAAAY2gvcGFyYW5vci9Q SwMECgAAAAAAonu8
LgAAAAAAAAAAAAAAABAAAABjaC9wYXJhbm9yL2VwbGEvUEsDBAoAAAAAAKJ7 vC4AAAAAAAAAAAAA
AAAaAAAAY2gvcGFyYW5vci9lcGxhL3N0cnVjdHVyZS9QSwMEFAAIAAgAtX28 LgAAAAAAAAAAAAAA
ACgAAABjaC9wYXJhbm9yL2VwbGEvc3RydWN0dXJlL0pFVENUYXNrLmNsYXNz lVgLfFPlFf9/bUpC
CFBSQFoKBgRM00dQcSqgE1rAYlsYrUBhU26Tr+mlaW7MvYGyOV9TnLpN58Y2 3Mttbsy5h8+U2aHu
hUPn3u/3e+49997c6/99N2nSNl1Z+2tv7v3OOd85//M/5zs3T//7scdRiWbR KLA8NhBNGxkjZWWi
Mp00oraTycacbEZGt27qae0x7EEvhECtlUlEjbQRG5BRx7KSdtRIOVF3uVIg 4Mghajtys5mUAnM6
9hsHjKhpRdX9OgFvXNpOm5kRmEUbg0ZCdhlDFAy6gkkjlYh2OxkzlaDwzFjS sG1XwNvTuf2qtvYd
Ar71saSZMp1LBCrDDTsFPK1WnBKB0q28mMvd1ZMW02pxhtJxM+PDPIHqkn0O 2fTWixo6k5DO9oyV
lhnnkMCq8GRvGiY/CmABFvoxH2cIzFifd2lBOd2dAdSizo9qLA5gFmbMRAWW CMztMFOyKzvUJzM9
Rl9Sw2DFjOROI2Oqe/1Qqc72w4NljNQZMG2BFR3TJ0thLYdlLOvQrH/TcEym HdNKUfusshncmDWT
8TExL84m0OmMbB2QscEAGpQLFYgEUOV630TvidmGPttKZgvZrg43jM93AC2I qrBXC1Q51hU7OkqE
UtKJ8gmFzsV5SmhNIYf5FS9eRCccy0VRYH64bBIuxEV+XIC1RC9mDaW5LzHo ydOQxJ46mUU31+Ni
FR/zV1OwQYGikXnh8Roqo5dig9LZyOTHZVIqMfJxTwBt2KTC2Uznk0ynwlPg zI6ysHfkBejDZWif
yTRvFbig1OWegYx1UBFh3TQWXJZ1+BFGJ+MoWijJ6jZSvVChV+xoJzOUWLeV zcTovuDfgo4yiiTT
LFs6RTz8vGtjJbOqAvC6lNjFePm4VdXs+DrToHuxh1a46LSn4nJ4Wz/pHG5v aA/gpXiZH3txZQB+
zFSW9rH07Wyfnc/7wnB7e9nM9yGmFOMB+FzFflV/U8kOKFmTRBx0PfQqX9os h3ETiOVdVkj1JjOl
0QwxMhlzrMyhkJ2WMbPflHEfmEc/ddklejJZqTzbU77a07hacUO1OdNuK5gK wHGpkaXqRL2N2f5+
mfHioMDq7sKWU7gUt6QdSllOSA6btrM25MMhP4axmFQ00mmZigs0lXJoW99+ apbpYe6mhOcavFJZ
uFb9YyXVEY0CT0L9ZHwpCjdwG9NWdRDAq9yAbmJbKTo9pjnZz8MCTNaraUFe nTWS9oSGWXCUVXQb
blcJe43AMk2pUIrnQChmpJS9PhniHg6To8Pw4XUCYVUekmdD2pZROdQfjfFY SMhUdD/bCVtCSRnc
KbCktJ67LGezlU2V9r+7BM6exmCr2ymYszf6cUShP2+7kbHpTxEBH97MtpC0 EgEcVSeAB3eTgezd
NsF7m+qqR/B29/zpHlRdRPWKRja6afYuCDN178Q9ysq7eDZzIc8S84AMDZm2 dsZM0Y33KLZOJmu7
YutRvFd59j56SvM+vJ+RaMmsYyajlxn2QKeR9uIDftyvTqG5A0YqnpRthY0E UmUsTxdBp5EZPE2h
oi/0Q9fXh/BhFfNHpk9SASgvHuTxUuhPaqYI4GGVkYfwCCcFLmwvziMB5Nyl Eeokxul8VJ02D+Ex
9o8DRjIrVR9bdVq1xlR9DCcUpx8nBVrUsg9PTqjUKaeNkkr9hCrST7LiJhxK Uw0en1YVelKgviDt
2pLxbVknnXUoKw2OQZ8RWFRqb/zq08oSD7xn8FkSrbhzqVR+v8/5cQqfFzhj i0zJDHsXOajEQ7Y+
Z0jGL/KoSLiLhPTLSuMIvsIyYNIKVSUwbREURNepk2esek6/dtjNHSPD/Lrj ywxLx8JCKR+dQKiI
sEuJyX3ju+Ok2lO2w0Pa1A28ROr746WSSZkwkhtiMWnbJVI/5NhQlOqyurOx gU7pDFilG/6Y/aIo
lJH9SdKPGx/IzwU9OsIShZ+SsGUnCedQWtpRgjqk6pujqRc/9+M5VfJzYkTA kRsyieyQTBGi8/It
anojKwpK5O4v8Stl8NcCFc08SH4rEP0/jXjxe3fM2KmKL4A/qDp9Hn9kOdpu HgP4s+Lp8/gL+cxh
rsXOplq0aV1ysZZOw0z58Df2sQnZ9OIfNNNvZdw3jpXT1KXWYVD/xL/8eAH/ Jn1T8qCbcTVNjR9X
820hwGlDUFxUcKv8qOkTnnHzkivqFTN0lRQGqppwmc2FT8z0C6/wc2KiqEsO gUvLuL53knapvQJv
XAs0HBCzlZtzWOxumU2sYscK+US12x8L2dHHecPeMq1PBEUNUy/mF5pMmV29 YqGaLMjcQcJ3UZmm
uvd/99kxjBeJWr84Q9TxQIsNEY/waXKVJS5iPPwmQcVMxMb6UnDylpyYpgZT YM1U5+M007w4i9O8
WMFJWQ6nubPgCO0dYpPgOcXm5c7tbvOaXXjx0yzHMk6fHoCvaxXqlY2fKtSc rq8clvXVr6916oWU
Vz+fBzAbLHbeXYhKqJ/qUVT3BoPHsWgE9Q9j6YNa80z+n6MlVlFnJeZiCUJ6 BdSvHbMS5VUoLyIj
WF5UnaEfuioBVwBnYYVWXknlCpoF3WfitJl7+VlttoZmGiOPoDmHc3I4P4d1 HZHGEby4M9I0gtam
HLbsOsbkjSLcq8QuH0HXEw/SiodWV2J7fvdVOuwGPm3GPDQhSDcXYTX9OYdS 53L9PP6er72LaBDX
5L0LogYvoTY5TC93MA7l6Wx0o0cHegU25AO/hCsKjBmRxkfRXIzcr59eyHgv 0vYXulJ5++pTlUZH
YGd5W7sn2lpPjYunsOXN2+plkl1b1+SRjDRWt+Rw1cX1FfdglrJrHMOiSGNl fQ7yUSQijfWefTns
5/PifnWaJptpdQvU2+p8bMVSXE4kO/X+Idfy2P4RDGqsvHySxJCOoqFMdp9l BIoD10WYs90n4fUc
g6cyaI3A1k9yODCK4d7gy0fwCvf+uhyuz682j8nfWHiSw81a/hZXvrko/wiM k6hTQkbw1hxeexTe
Sup6gndwtRhohNCCdAky2TVMcx0T3MzPq5nmjUzyPuxCArtxLfaUUPi6fOAV 6suEfJCKIK/HG1SY
wuSdAvDUKI70krVv6oxoN98yzs0c3koev4N/7+5qfgpRV+becTKeHI41Be8T YhT3947ggzk8oOXd
+GY1q2sOj/KSyN8mcjiuCvkhLFX2aGf0OJ6g0eDHc/iURueptZ5RnOodxTO9 tZ4RPDuCL6ytcnf/
EgVrPUX/aqty+Gqt54ExwLYSKuBKZvsqArKPMMSY6ThBk9iEfsKWIAdNruzH ALlgkQ0H+Y58FDbu
Q4ZvFQ6eRBYncUADeokL1BiTTuWrbialvoavax7dg2/gm2TcUablW5T30MpS fBvf0S3vUlaPmwL1
jdX38AP8CD/Bz3QiKvOJsEfxHOH7RSfB+03wdzn8SX1wGfZX9bGR1+Dfj+M/ Xc05UbnW01wjqjwn
8EJvZeUJ7M2JWd05MTcPUo2YN46exKm2qtbjOSG8vZVNObGAsot3FTm2VlP/ evbcG9iEbkQ936RX
4CZy72YGdJgt5zBlbiEUtzCUwyy5WwnubQTr9hKI7DGIbN2OeExhUNSLJeq7 OrSLpeJMQrQarSIk
lhGiLWjirLFcQ5TG1ZNKcXe+PQQX3606f7i3SbdRsfKJiX3/DkreSc/vKin9 4Jg3QbFKnK2rIijC
UN/MCNGgLIjIfwFQSwcImbSYcccKAAB0FgAAUEsBAhQAFAAIAAgAFn68LgAA AAACAAAAAAAAAAkA
BAAAAAAAAAAAAAAAAAAAAE1FVEEtSU5GL/7KAABQSwECFAAUAAgACAAWfrwu IIjsVEcAAABHAAAA
FAAAAAAAAAAAAAAAAAA9AAAATUVUQS1JTkYvTUFOSUZFU1QuTUZQSwECCgAK AAAAAACie7wuAAAA
AAAAAAAAAAAAAwAAAAAAAAAAAAAAAADGAAAAY2gvUEsBAgoACgAAAAAAonu8 LgAAAAAAAAAAAAAA
AAsAAAAAAAAAAAAAAAAA5wAAAGNoL3BhcmFub3IvUEsBAgoACgAAAAAAonu8 LgAAAAAAAAAAAAAA
ABAAAAAAAAAAAAAAAAAAEAEAAGNoL3BhcmFub3IvZXBsYS9QSwECCgAKAAAA AACie7wuAAAAAAAA
AAAAAAAAGgAAAAAAAAAAAAAAAAA+AQAAY2gvcGFyYW5vci9lcGxhL3N0cnVj dHVyZS9QSwECFAAU
AAgACAC1fbwumbSYcccKAAB0FgAAKAAAAAAAAAAAAAAAAAB2AQAAY2gvcGFy YW5vci9lcGxhL3N0
cnVjdHVyZS9KRVRDVGFzay5jbGFzc1BLBQYAAAAABwAHAMMBAACTDAAAAAA=
------=_NextPart_000_000E_01C32531.6DBCC9A0
Content-Type: application/octet-stream;
name="JETCTask.java"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="JETCTask.java"
package ch.paranor.epla.structure;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Commandline;
import org.eclipse.emf.codegen.jet.JETCompiler;
import org.eclipse.emf.codegen.jet.JETException;
import org.eclipse.emf.codegen.jet.JETSkeleton;
/**
* This task compiles a JET template into a Java class by using the JET =
framework and Ant's <javac/> task.
*
* Usages:
* <pre>
* <jetc template=3D"my-template.xmljet" destdir=3D"classes"/>
* <jetc template=3D"my-template.xmljet" class=3D"com.foo.Bar" =
destdir=3D"classes"/>
* </pre>
*/
public class JETCTask extends Task {
private File templateFile;
private File destDir;
private String packageName;
private String className;
private static final File TMP_DIR =3D
new File(System.getProperty("java.io.tmpdir"));
public void execute() throws BuildException {
preCheck();
try {
String templateURI =3D
templateFile.getAbsoluteFile().toURL().toString();
File javaSource =3D compileJETTemplate(templateURI);
compileJavaTemplate(javaSource);
javaSource.delete();
} catch (Exception e) {
throw new BuildException(e, location);
}
}
public void setTemplate(File templateFile) {
this.templateFile =3D templateFile;
}
public void setDestdir(File destDir) {
this.destDir =3D destDir;
}
/**
* Sets the class name of the template emitter to create.
* Note that this overrides the JET directives <code>class</code> and =
<code>package</code> in the template.
*=20
* @param klass Fully qualified name of class
*/
public void setClass(String klass) {
int lastDot =3D klass.lastIndexOf('.');
if (lastDot =3D=3D -1) {
className =3D klass;
} else {
packageName =3D klass.substring(0, lastDot);
className =3D klass.substring(lastDot + 1);
}
}
private void preCheck() throws BuildException {
assertTrue(destDir !=3D null, "No destination directory specified");
assertTrue(
destDir.isDirectory(),
"Specified destination directory does not exist: " + destDir);
assertTrue(templateFile !=3D null, "No template file specified");
assertTrue(templateFile.isFile(), "Specified template does not exist: =
" + templateFile);
if (className !=3D null) {
assertTrue(!className.equals(""), "Class name cannot be empty =
string");
}
}
private File compileJETTemplate(String templateURI)
throws JETException, FileNotFoundException {
JETCompiler jetCompiler =3D new JETCompiler(templateURI);
log("Parsing template " + templateFile);
jetCompiler.parse();
// initialize skeleton
JETSkeleton skeleton =3D jetCompiler.getSkeleton();
if (skeleton =3D=3D null) {
log("JET directive missing in " + templateFile, Project.MSG_WARN);
jetCompiler.handleDirective("jet", null, null, new HashMap());
skeleton =3D jetCompiler.getSkeleton();
}
if (className !=3D null) {
skeleton.setClassName(className);
}
if (packageName !=3D null) {
skeleton.setPackageName(packageName);
}
File targetFile =3D new File(TMP_DIR, skeleton.getClassName() + =
".java");
OutputStream output =3D
new BufferedOutputStream(new FileOutputStream(targetFile));
log("Generating java source " + targetFile);
jetCompiler.generate(output);
return targetFile;
}
private void compileJavaTemplate(File javaSource)
throws
ClassNotFoundException,
InstantiationException,
IllegalAccessException,
NoSuchMethodException,
InvocationTargetException {
Commandline cmd =3D new Commandline();
cmd.createArgument().setValue("-d");
cmd.createArgument().setFile(destDir);
cmd.createArgument().setFile(javaSource);
Class c =3D Class.forName("com.sun.tools.javac.Main");
Object compiler =3D c.newInstance();
Method compile =3D c.getMethod("compile", new Class[] {(new String[] {
}).getClass()
});
log("Compiling java source to " + destDir);
compile.invoke(compiler, new Object[] { cmd.getArguments()});
}
private void assertTrue(boolean expr, String message)
throws BuildException {
if (!expr) {
throw new BuildException(message, location);
}
}
}
------=_NextPart_000_000E_01C32531.6DBCC9A0--
|
|
|
| Re: getting started with JETEmitter [message #377648 is a reply to message #377646] |
Wed, 28 May 2003 11:27   |
Knut Wannheden Messages: 283 Registered: July 2009 |
Senior Member |
|
|
This is a multi-part message in MIME format.
------=_NextPart_000_000E_01C3253E.7676E7D0
Content-Type: multipart/alternative;
boundary="----=_NextPart_001_000F_01C3253E.7676E7D0"
------=_NextPart_001_000F_01C3253E.7676E7D0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Couldn't keep my self from adding <fileset/> support :-)
Now you can either use the attribute "template" (optionally in =
conjunction with "package" and/or "class") or nested <fileset/>s. But =
not both!
Also I removed the part that invokes <javac/>. So now you have to do =
that separately in the buildfile. Example (compiles all JET templates =
in "jet-templates" to "classes" and deletes the temporary directory used =
for java sources):
<target name=3D"jetc">
<mkdir dir=3D"jet-output"/>
<jetc destdir=3D"jet-output">
<fileset dir=3D"jet-templates" includes=3D"*.*jet"/>
</jetc>
<javac srcdir=3D"jet-output" destdir=3D"classes"/>
<delete dir=3D"jet-output"/>
</target>
Cheers,
--
knut
"Knut Wannheden" <knut.wannheden@paranor.ch> wrote in message =
news:bb2f2o$23i$1@rogue.oti.com...
Remko,
Here you go (source and jar)!
Some notes:
a.. The task both runs the JET compiler and Ant's <javac/>, so the =
final result is a .class file. But it's easy to change so it only =
performs the first step.=20
b.. The task only handles a single template at the time. An obvious =
and simple improvment would be to make the task handle nested =
<fileset/>s.=20
c.. In the <taskdef/> you have to specify the classpath to include =
both this task as well as the jars of the plugins I mentioned in the =
earlier mail.=20
d.. The task supports the "class" attribute (FQCN) which overloads =
the JET directives "class" and "package" in the template. It can also be =
used if the JET directive is missing altogether. I added this attribute =
because sometimes I want to specify the class to generate outside the =
template. (This attribute of course doesn't make any sense if the task =
is enhanced to work with whole <fileset/>s.)
Here's a simple Ant buildfile (the taskdef classpath assumes you have =
Eclipse 2.1 and EMF 1.1.0):
<project default=3D"jetc">
<property name=3D"eclipse.plugins.dir" =
location=3D"C:/Products/eclipse-2.1/plugins"/>
<taskdef name=3D"jetc" =
classname=3D"ch.paranor.epla.structure.JETCTask">
<classpath>
<pathelement location=3D"jetc-task.jar"/>
<fileset dir=3D"${eclipse.plugins.dir}">
<include name=3D"org.eclipse.core.boot_2.1.0/boot.jar"/>
<include =
name=3D"org.eclipse.core.resources_2.1.0/resources.jar"/>
<include name=3D"org.eclipse.core.runtime_2.1.0/runtime.jar"/>
<include =
name=3D"org.eclipse.emf.codegen_1.1.0/runtime/codegen.jar"/ >
<include name=3D"org.eclipse.jdt.core_2.1.0/jdtcore.jar"/>
</fileset>
</classpath>
</taskdef>
<target name=3D"jetc">
<jetc template=3D"test.xmljet" class=3D"com.foo.Test" =
destdir=3D"."/>
</target>
</project>
Hope you can work with this! And be sure to notify me of any =
improvements you make! :-)
--
knut
"Remko Popma" <remko.popma@azzurri.jp> wrote in message =
news:baubb1$tj7$1@rogue.oti.com...
Knut,
I'm definitely interested. Can you post it here or send it to me by =
email?
Thanks.
Remko
"Knut Wannheden" <knut.wannheden@paranor.ch> wrote in message =
news:batn96$hf6$1@rogue.oti.com...
Great!
I've been using JET in a standalone application for some time now. =
But I'm not using dynamic templates, so I precompile the templates =
inside Eclipse first and then use them in the standalone application, =
where no JET runtime is required anymore. I actually also wrote a =
simple Ant task to compile the JET templates outside Eclipse. I then =
compile the generated source using Ant's usual <javac/> and can load the =
class with reflection. But it never occured to me that maybe JETEmitter =
could be used. I'll have to investigate that.
Note on the Ant task: To get it to work I need the jars of the =
following plugins on the classpath: org.eclipse.core.boot, =
org.eclipse.core.runtime, org.eclipse.core.resources, =
org.eclipse.jdt.core, and org.eclipse.emf.codegen. This is rather a =
lot... But if anyone is interested I'd be happy to send the Ant task.
--
knut
------=_NextPart_001_000F_01C3253E.7676E7D0
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.2800.1170" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3DArial size=3D2>Couldn't keep my self from adding =
<fileset/>=20
support :-)</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Now you can either use the attribute =
"template"=20
(optionally in conjunction with "package" and/or "class") or nested=20
<fileset/>s. But not both!</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Also I removed the part that invokes=20
<javac/>. So now you have to do that separately in the=20
buildfile. Example (compiles all JET templates in "jet-templates" =
to=20
"classes" and deletes the temporary directory used for java=20
sources):</FONT></DIV>
<BLOCKQUOTE dir=3Dltr style=3D"MARGIN-RIGHT: 0px">
<DIV><FONT face=3D"Courier New" size=3D2> <target=20
name=3D"jetc"></FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2> <mkdir=20
dir=3D"jet-output"/><BR> <jetc=20
destdir=3D"jet-output"><BR> <fileset =
dir=3D"jet-templates"=20
includes=3D"*.*jet"/><BR> </jetc><BR> <javac=20
srcdir=3D"jet-output" destdir=3D"classes"/><BR> <delete=20
=
dir=3D"jet-output"/><BR> </target> </FONT></DIV></BLOCKQUOTE=
>
<DIV dir=3Dltr><FONT face=3DArial size=3D2>Cheers,</FONT></DIV>
<DIV dir=3Dltr><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV dir=3Dltr><FONT face=3DArial size=3D2>--</FONT></DIV>
<DIV dir=3Dltr><FONT face=3DArial size=3D2>knut</FONT></DIV>
<BLOCKQUOTE dir=3Dltr=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
<DIV>"Knut Wannheden" <<A=20
=
href=3D"mailto:knut.wannheden@paranor.ch">knut.wannheden@paranor.ch</A>&g=
t;=20
wrote in message <A=20
=
href=3D"news:bb2f2o$23i$1@rogue.oti.com">news:bb2f2o$23i$1@rogue.oti.com<=
/A>...</DIV>
<DIV><FONT face=3DArial size=3D2>Remko,</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Here you go (source and =
jar)!</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Some notes:</FONT></DIV>
<UL>
<LI><FONT face=3DArial size=3D2>The task both runs the JET compiler =
and Ant's=20
<javac/>, so the final result is a .class file. But it's =
easy to=20
change so it only performs the first step.</FONT>=20
<LI><FONT face=3DArial size=3D2>The task only handles a single =
template at the=20
time. An obvious and simple improvment would be to make the task=20
handle nested <fileset/>s.</FONT>=20
<LI><FONT face=3DArial size=3D2>In the <taskdef/> you have to =
specify the=20
classpath to include both this task as well as the jars of the =
plugins I=20
mentioned in the earlier mail.</FONT>=20
<LI><FONT face=3DArial size=3D2>The task supports the "class" =
attribute (FQCN)=20
which overloads the JET directives "class" and "package" in the =
template. It=20
can also be used if the JET directive is missing altogether. I added =
this=20
attribute because sometimes I want to specify the class to generate =
outside=20
the template. (This attribute of course doesn't make any sense =
if the=20
task is enhanced to work with whole =
<fileset/>s.)</FONT></LI></UL>
<DIV><FONT face=3DArial size=3D2>Here's a simple Ant buildfile (the =
taskdef=20
classpath assumes you have Eclipse 2.1 and EMF 1.1.0):</FONT></DIV>
<BLOCKQUOTE dir=3Dltr style=3D"MARGIN-RIGHT: 0px">
<DIV><FONT face=3D"Courier New" size=3D2><project=20
default=3D"jetc"></FONT></DIV>
<DIV><FONT face=3D"Courier New"></FONT> </DIV>
<DIV><FONT face=3D"Courier New" size=3D2> <property=20
name=3D"eclipse.plugins.dir"=20
location=3D"C:/Products/eclipse-2.1/plugins"/></FONT ></DIV>
<DIV><FONT face=3D"Courier New"></FONT> </DIV>
<DIV><FONT face=3D"Courier New" size=3D2> <taskdef =
name=3D"jetc"=20
classname=3D"ch.paranor.epla.structure.JETCTask"><BR > =20
<classpath><BR> <pathelement=20
location=3D"jetc-task.jar"/><BR> <fileset=20
dir=3D"${eclipse.plugins.dir}"><BR> <include=20
name=3D"org.eclipse.core.boot_2.1.0/boot.jar"/><BR > =
<include=20
=
name=3D"org.eclipse.core.resources_2.1.0/resources.jar"/> <BR> &nb=
sp;=20
<include=20
=
name=3D"org.eclipse.core.runtime_2.1.0/runtime.jar"/> <BR> =
<include=20
=
name=3D"org.eclipse.emf.codegen_1.1.0/runtime/codegen.jar"/> <BR> =
=20
<include =
name=3D"org.eclipse.jdt.core_2.1.0/jdtcore.jar"/><BR > =20
=
</fileset><BR> </classpath> <BR> </taskdef></F=
ONT></DIV>
<DIV><FONT face=3D"Courier New"></FONT> </DIV>
<DIV><FONT face=3D"Courier New" size=3D2> <target=20
name=3D"jetc"><BR> <jetc template=3D"test.xmljet"=20
class=3D"com.foo.Test" =
destdir=3D"."/><BR> </target> </FONT></DIV>
<DIV><FONT face=3D"Courier New"></FONT> </DIV>
<DIV dir=3Dltr><FONT face=3D"Courier New"=20
size=3D2></project></FONT></DIV></BLOCKQUOTE >
<DIV dir=3Dltr><FONT face=3DArial size=3D2>Hope you can work with =
this! And be=20
sure to notify me of any improvements you make! :-)</FONT></DIV>
<DIV dir=3Dltr><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV dir=3Dltr><FONT face=3DArial size=3D2>--</FONT></DIV>
<DIV dir=3Dltr><FONT face=3DArial size=3D2>knut</FONT></DIV>
<BLOCKQUOTE dir=3Dltr=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
<DIV>"Remko Popma" <<A=20
=
href=3D"mailto:remko.popma@azzurri.jp">remko.popma@azzurri.jp</A>> =
wrote in=20
message <A=20
=
href=3D"news:baubb1$tj7$1@rogue.oti.com">news:baubb1$tj7$1@rogue.oti.com<=
/A>...</DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Knut,</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>I'm definitely =
interested. Can you post it=20
here or send it to me by email?</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Thanks.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Remko</FONT></DIV>
<DIV> </DIV>
<BLOCKQUOTE dir=3Dltr=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
<DIV>"Knut Wannheden" <<A=20
=
href=3D"mailto:knut.wannheden@paranor.ch">knut.wannheden@paranor.ch</A>&g=
t;=20
wrote in message <A=20
=
href=3D"news:batn96$hf6$1@rogue.oti.com">news:batn96$hf6$1@rogue.oti.com<=
/A>...</DIV>
<DIV>
<DIV><FONT face=3DArial size=3D2>Great!</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>I've been using JET in a =
standalone=20
application for some time now. But I'm not using dynamic =
templates,=20
so I precompile the templates inside Eclipse first and then use =
them in=20
the standalone application, where no JET runtime is required=20
anymore. I actually also wrote a simple Ant task to compile =
the JET=20
templates outside Eclipse. I then compile the generated =
source using=20
Ant's usual <javac/> and can load the class with =
reflection. =20
But it never occured to me that maybe JETEmitter could be =
used. I'll=20
have to investigate that.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Note on the Ant task: To get it =
to work I=20
need the jars of the following plugins on the classpath:=20
org.eclipse.core.boot, org.eclipse.core.runtime,=20
org.eclipse.core.resources, org.eclipse.jdt.core, and=20
org.eclipse.emf.codegen. This is rather a lot... But =
if anyone=20
is interested I'd be happy to send the Ant task.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>--</FONT></DIV>
<DIV><FONT face=3DArial=20
size=3D2>knut</FONT></DIV></DIV></BLOCKQUOTE></BLOCKQUOTE ></BLOCKQUOTE></=
BODY></HTML>
------=_NextPart_001_000F_01C3253E.7676E7D0--
------=_NextPart_000_000E_01C3253E.7676E7D0
Content-Type: application/octet-stream;
name="JETCTask.java"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="JETCTask.java"
package ch.paranor.epla.structure;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.FileSet;
import org.eclipse.emf.codegen.jet.JETCompiler;
import org.eclipse.emf.codegen.jet.JETException;
import org.eclipse.emf.codegen.jet.JETSkeleton;
/**
* This task compiles JET templates into Java source files using the EMF =
JET framework.
*/
public class JETCTask extends Task {
private File destDir;
private List filesets =3D new ArrayList();
private List templateFiles =3D new ArrayList();
private File templateFile;
private String packageName;
private String className;
public void execute() throws BuildException {
preCheck();
// check that filename ends in 'jet'?
if (templateFile !=3D null) {
templateFiles.add(templateFile);
}
for (Iterator i =3D filesets.iterator(); i.hasNext();) {
FileSet fs =3D (FileSet) i.next();
DirectoryScanner ds =3D fs.getDirectoryScanner(getProject());
File fromDir =3D fs.getDir(getProject());
String[] includedFiles =3D ds.getIncludedFiles();
for (int j =3D 0; j < includedFiles.length; j++) {
templateFiles.add(project.resolveFile(includedFiles[j]));
}
}
try {
compileJETTemplates();
} catch (Exception e) {
throw new BuildException(e, location);
}
}
public void setDestdir(File destDir) {
this.destDir =3D destDir;
}
public void setTemplate(File templateFile) {
this.templateFile =3D templateFile;
}
public void setPackage(String packageName) {
this.packageName =3D packageName;
}
public void setClass(String className) {
this.className =3D className;
}
public void addFileset(FileSet fileset) {
filesets.add(fileset);
}
private void preCheck() throws BuildException {
assertTrue(destDir !=3D null, "No destination directory specified");
assertTrue(
destDir.isDirectory(),
"Specified destination directory does not exist: " + destDir);
assertTrue(
templateFile !=3D null || filesets.size() > 0,
"No template files specified");
if (templateFile !=3D null) {
assertTrue(
templateFile.isFile(),
"Specified template does not exist: " + templateFile);
} else {
assertTrue(
className =3D=3D null && packageName =3D=3D null,
"Attributes \"class\" and \"package\" can only be used together with =
attribute \"template\"");
}
}
private void compileJETTemplates()
throws MalformedURLException, JETException, FileNotFoundException {
log(
"Compiling "
+ templateFiles.size()
+ " JET template(s) to "
+ destDir);
for (Iterator i =3D templateFiles.iterator(); i.hasNext();) {
File template =3D (File) i.next();
compileJETTemplate(template, destDir);
}
}
private File compileJETTemplate(File template, File outputDir)
throws JETException, FileNotFoundException, MalformedURLException {
String templateURI =3D template.getAbsoluteFile().toURL().toString();
JETCompiler jetCompiler =3D new JETCompiler(templateURI);
log("Parsing template " + template, Project.MSG_VERBOSE);
jetCompiler.parse();
// initialize skeleton
JETSkeleton skeleton =3D jetCompiler.getSkeleton();
if (skeleton =3D=3D null) {
log("JET directive missing in " + templateFile, Project.MSG_WARN);
jetCompiler.handleDirective("jet", null, null, new HashMap());
skeleton =3D jetCompiler.getSkeleton();
}
if (className !=3D null) {
skeleton.setClassName(className);
}
if (packageName !=3D null) {
skeleton.setPackageName(packageName);
}
File packageDir =3D
new File(outputDir, skeleton.getPackageName().replace('.', '/'));
packageDir.mkdirs();
File targetFile =3D
new File(packageDir, skeleton.getClassName() + ".java");
OutputStream output =3D
new BufferedOutputStream(new FileOutputStream(targetFile));
log("Generating java source " + targetFile, Project.MSG_VERBOSE);
jetCompiler.generate(output);
return targetFile;
}
private void assertTrue(boolean expr, String message)
throws BuildException {
if (!expr) {
throw new BuildException(message, location);
}
}
}
------=_NextPart_000_000E_01C3253E.7676E7D0
Content-Type: application/octet-stream;
name="jetc-task.jar"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="jetc-task.jar"
UEsDBBQACAAIAFqKvC4AAAAAAAAAAAAAAAAJAAQATUVUQS1JTkYv/soAAAMA UEsHCAAAAAACAAAA
AAAAAFBLAwQUAAgACABbirwuAAAAAAAAAAAAAAAAFAAAAE1FVEEtSU5GL01B TklGRVNULk1G803M
y0xLLS7RDUstKs7Mz7NSMNQz4OVyLkpNLElN0XWqBAmY6BnGGxgpaASX5in4 ZiYX5RdXFpek5hYr
eOYl62nycvFyAQBQSwcIIIjsVEcAAABHAAAAUEsDBAoAAAAAAKJ7vC4AAAAA AAAAAAAAAAADAAAA
Y2gvUEsDBAoAAAAAAKJ7vC4AAAAAAAAAAAAAAAALAAAAY2gvcGFyYW5vci9Q SwMECgAAAAAAonu8
LgAAAAAAAAAAAAAAABAAAABjaC9wYXJhbm9yL2VwbGEvUEsDBAoAAAAAAKJ7 vC4AAAAAAAAAAAAA
AAAaAAAAY2gvcGFyYW5vci9lcGxhL3N0cnVjdHVyZS9QSwMEFAAIAAgAgom8 LgAAAAAAAAAAAAAA
ACgAAABjaC9wYXJhbm9yL2VwbGEvc3RydWN0dXJlL0pFVENUYXNrLmNsYXNz jVgJfBTVGf+/XJts
JpCDgAuoS4CwOWARFSWxIoTDaBKQBDDgNdmdJEM2O9uZWSBUqVRtverRQ6tt rfaQHrbVVjdi6tEL
qm2ld2vtaVutvWtPK1X/b2Z2s9lsCD9+7My8973/+47/933v5ZnXH3sChVgq QgJ1kcFwQjXVuGGG
tURMDVu2mYzYSVMLX7C+p61HtYZ8EAIBwxwIqwk1MqiFbcOIWWE1bofd6UIB X1Sz7HW6KTCjY5e6
Ww3rRniDHtNaBUr7+bQ02xKodOeSth4Ld+iWzdkKWxvmtrYmpSmiZH8LlHPH IXVA61KH+VXtro+p
8YFwt23q8QEilEViqmW5AiXn6HHdPlegMNSwTaCozYhqCmZgph9FqBKoGd9/ jWmqI1IJH2r8mIUq
BT6UlqEAsxWUuW8nCczs0ONaV3K4TzN71L6Yo4QRUWPbVFOX395gkT2oU/tF HdO7kyr7tL1aJGlz
nX/93oiWsHUjztUL8/p4bVKPRTNiPgTp0oSptQ1qkSEFddK2AixU4EeJ1Hkx QzDRyz4soUPUaFSg
NpTlwU19u7SI3dqwQ0EDGssRQhOhdVszVdtgJGeHGrLi1e6NtypYimVSOkxf TJ734TS6I67ttQVm
pRGy91NwOs4oxwqcSfbltdgeSWiWQ59ujdqfJbA4r9xm05CIbcZwwohrcYqu okcHNNubEAhSgeMt
pTKtOMePFrxFoPE4yqzpYyDViJ1RajXJxJ1IecIY5kh3RI3HNXptY+j4O06h UC4QNVuDtX6chzbS
2t1JYNm04BOST8F6bJAYG6dyYe62PrQzTbldezwSS0a1qJeWtaGGnZOTT8GF 6PDjAnSS04m000+Z
zuWbsLmMLr9IYP7xJH3oZgEwNcuI7fbKQV1oshKTbN6KbX70YDt1GlStLoeJ rAekeS92SOLtZOwi
JA3FmZQ9XsGxFFzqJtNlTIMYk1zmm8Cp+c3p8AS44RVQy1hf+gTOytavZ9A0 9sjy0DoNQsM2WaOi
fiyAlq5RDkJW1g8ICJ0ZlS8jBQr6neIzfTZJ2Shll5wgC+nDftMYdshXoU/k RE0eRlDLXfxPEgma
UtuRxxbKlLMdpN0uUBWaGEFZuf2UWMeWEtVNBcVuZRtxhze7HSGnmKXJQFeW Q5HiVzGKFG+T3UFB
hTt4NTFYCTe4LYl+mCKhJjpNauTrT6+p6zKCst3pcSd8wWjaaUEroUX0fl2L luI6uZFlaabdYyY1
WUx35Nf2Xbhecu4Gtr5sL/hwE/2kW5mIKHg3dvhxM24hWC7S2mR/v0ze2wSW d6eVmELJqKFZwbhh
B7W9bA4twVK8R9LvSj9ux/tYa9REQouzVzTn6xWTbHB3ZhLcgTslwgfoddtw 53IbQKZq3I0PStkP
sVFY+j7NSc92BffgI7Kv3Cswjy5OHwSCjuOzfftRaqlb0ksKPu465RPsnuOG Z5ZOtvWgwPo1NhXp
Y/8N1jlnh7og2R404rGRYJ8WTFoSwWANHNTM4B7dHgyq4wvS0HWl+BRLnWNc XLPDnWqs3zCHtejW
LR1ZafsZgZAkmBaJ6QlLC2vD/eEIDyUDWjy8i8tYf7KkPytwcjYJugx7g5GM Z3f/z5NXbU7toitp
z0N0Vqj9uHH5ovT1wwxGkLtlfBOyGmglEVI5oZ5YVvNDPiohDzFuMWNAwZgk TxG+xPPA5LI6jp7O
75xszy3fT+BJmRBPSSJlMGYyHOzBRiyZPhlWhiat/Cq+JrnwdYFi22AcsoRk iDhCoSP4hhR6Op1v
3owP3/TjW5KSS6aJl+t9mW3P+nFUpkzVZtW0ZDgyvCvFd2XKT/Zqu0z5MXxf +usH1JNnRYss/pFs
PEfxY6Y8De0e0mKaLXtPk3d+OY46aWGa9hx+KlGe52ldRtpNeX23FhzWLUc/ PU7Nfs6wcW0pfknN
x7vJ+ao12KkmfPi1Hy/Is/LMQTUejWnr0igC8TwGTadep2oOnaDQuC7Uw6mN v8XvpEEvTh+UtBd8
+D0Dmy778lKg4A+Sni/jjzwYj7cPd+rP7tRfODWQM/U3WaNext9JolyjffgH +4Epz/cRp7S3teUt
c//Cv/34J/7D2pQ3BXJbwQy8Kqn5P5a34SFGj23rmFve/k+jBiYY9YajHtss fLvVWFLb1C9Qf0IV
u1URBaKQiokiEnCZnC4VJTyLpTV081yLbkraiaTNRZo67BOlAidl2zBx1i+1 3+MX5UIh+8atzZZy
bRQz/KJMzBSYs1GLywOMJKYUD1pG0owwdwTJVzrgTmqKqOEKHBWzeNMzHDTn MFKezrWtW3jYKCcN
0nkpMG3OpEXl7dTKJNuJpxprsHcvdXTx26rJ6Lh1qcRVkrTI7wSBM6ZKo2lO iCLIE6JYwKap7U1w
W7GDwR/WLMs5Dfm7Hfe5SlSkL5tOeHmuLGC9AUr45GGKbwXysus8y7yn3xvn 6cl5VjjPchKM12f+
VvLrIhTyDZjXOIrqxjHM6h1F7SOYM/4aeMhZPJe/1c6Wc/l7CgFO5dtczOOI 4kJgPk7mUzizBZwH
JQVV5Uaije8+jtzKjRY1Poz6w6jiIyBfD6G5ANv5NucQlgt0HERn0yGsFHgK Z3c2N6ZwbgrruryX
81uKlqbQ1VJcuLLkIOZ7GFsCxbUlK1K42MW6tkTUlgSKn7jvjReIdInA3W88 yI0vP4iqjjEs6G3i
ksgo+p98iAqO4Gr+G/SMXOv4pZ7qNtBXjQigmV9LsRzLsAphtOE0tPPKsYmX Xo3PBOdHcDYRVuEA
70C34BzHKVucKNzqOWUhtkHHLu62nJe3IcS42yqchWHEGYE24huMVhGRlxDx rYxpBxbBhMXRA4yc
jSRkadiNPV7kziVCgWRAY9MjqB8Pkt8ZXU2E8xw9ZrtSnh7yTfJCYu3Nj7Uv F6uNWOumwCr2sN6G
K/Nh7c/F2sgV50+BVe4QSeDt+bEO5GJd6HgpP1aFh/UOXONhrfOwFMmzJpcm uYibqMPmLEQlg6jg
WsaMVy3555lccuM1aiJT4IZGgu87DF/RQRQVVr9zFDc6IyncOobbe6vfO4r3 u993pfBhb7b+CGa6
3L9P8MDsrf2YnHXSZJEjlML9DsQnXYj6DMRB1EqBA0fSKz/NwXHDulDD327m bg/ftnJsG8nWQxpu
J5EvJuF66cjtlNvB2Z2cvYSX5ktJwp0k2+WkyBV0oYrr+H49Iln5foPnnAJ5 yfZcUkoyP4DP4UHH
LY/TRYVy90ZH9S+4qgccQ1N4pHo0hcfG3ZHC4+6sWwLmpEvAzZ2NzVJqFF/e nk7mF8cNXOFUtQGq
NMgo6ozcLio5xDgNYjHHQ4zbmcyz1cy0dr5voWnSiKCrmmfECn67+bmaKF9x 6mqBPLhmGSbNesAp
Zs9yvoyjx5pSOJzCMyl8u2sMR3uXjuI7LUWutd+jtU2uZSUp/DBQlMJP5M/P WooDxUewwpX6xYRw
FjmC1b8SYgwvsPz+JoWXvDUyxIehBJyXFP7Ex/709/4U/jqGm3ubA8UpvFK5 rDKcwn9H8VpLSYBb
v75dzgVK5H4UEOJRUcxda4SP7nc49FqLb0yU9Y6J8t6Ab1RUjIrKllJHvxpR TdGAL9uOQGlK1AZ8
D2YicBnm8Ndm7iRRS9I0kjRh7MNKVoVW5nI3riJx9tO7V7OyHeDMNfy9FjeS UPfwtnwvqXQ/buI5
/kY8zfr5HO/Fz7NyvoLb8CpvJTJal7j+zuTjMSdGkobHxGwnWuU82M0hFwqp w0viJBEg+VbisJgr
5jE77yVv5lOuhDucLk7m08c9FohTxKmMbYG8s0/K6os9+lbPuxuVsms0O11D 1D05zr4ZjsQdlLwT
Vbgri1nVGV2rxUKxyNG1WiymhgUQol4iiCVvAlBLBwiUeQ/lSgsAALgXAABQ SwECFAAUAAgACABa
irwuAAAAAAIAAAAAAAAACQAEAAAAAAAAAAAAAAAAAAAATUVUQS1JTkYv/soA AFBLAQIUABQACAAI
AFuKvC4giOxURwAAAEcAAAAUAAAAAAAAAAAAAAAAAD0AAABNRVRBLUlORi9N QU5JRkVTVC5NRlBL
AQIKAAoAAAAAAKJ7vC4AAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAMYAAABj aC9QSwECCgAKAAAA
AACie7wuAAAAAAAAAAAAAAAACwAAAAAAAAAAAAAAAADnAAAAY2gvcGFyYW5v ci9QSwECCgAKAAAA
AACie7wuAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAQAQAAY2gvcGFyYW5v ci9lcGxhL1BLAQIK
AAoAAAAAAKJ7vC4AAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAD4BAABjaC9w YXJhbm9yL2VwbGEv
c3RydWN0dXJlL1BLAQIUABQACAAIAIKJvC6UeQ/lSgsAALgXAAAoAAAAAAAA AAAAAAAAAHYBAABj
aC9wYXJhbm9yL2VwbGEvc3RydWN0dXJlL0pFVENUYXNrLmNsYXNzUEsFBgAA AAAHAAcAwwEAABYN
AAAAAA==
------=_NextPart_000_000E_01C3253E.7676E7D0--
|
|
|
| Re: getting started with JETEmitter [message #377661 is a reply to message #377648] |
Thu, 29 May 2003 11:29   |
|
Originally posted by: remko.popma.azzurri.jp
This is a multi-part message in MIME format.
------=_NextPart_000_02A0_01C32642.7B7925E0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Finally had a chance to have a look. Very nice!
Your task and JEmitter seem to have a lot of similarities,
with some subtle differences. Calling generate on a JEmitter
will do the compilation and always invoke a method on the generated
class file. Your class allows you to store the intermediate java and or
class files, and call these classes later.
The biggest difference is that your task can be used outside of Eclipse,
as long as the jar files you mentioned are on the classpath, right? That's
very handy.
JETEmitter can only be used inside Eclipse (plugins must be initialized).
JETCompiler only refers to the plugin to get localized error messages
if an exception occurs, so as long as your pre-checking is strict enough
that no errors occur you should be ok.
Thanks for sharing the code!
Remko
"Knut Wannheden" <knut.wannheden@paranor.ch> wrote in message
news:bb2khn$7oj$1@rogue.oti.com...
Couldn't keep my self from adding <fileset/> support :-)
Now you can either use the attribute "template" (optionally in conjunction
with "package" and/or "class") or nested <fileset/>s. But not both!
Also I removed the part that invokes <javac/>. So now you have to do that
separately in the buildfile. Example (compiles all JET templates in
"jet-templates" to "classes" and deletes the temporary directory used for
java sources):
<target name="jetc">
<mkdir dir="jet-output"/>
<jetc destdir="jet-output">
<fileset dir="jet-templates" includes="*.*jet"/>
</jetc>
<javac srcdir="jet-output" destdir="classes"/>
<delete dir="jet-output"/>
</target>
Cheers,
--
knut
"Knut Wannheden" <knut.wannheden@paranor.ch> wrote in message
news:bb2f2o$23i$1@rogue.oti.com...
Remko,
Here you go (source and jar)!
Some notes:
a.. The task both runs the JET compiler and Ant's <javac/>, so the
final result is a .class file. But it's easy to change so it only performs
the first step.
b.. The task only handles a single template at the time. An obvious
and simple improvment would be to make the task handle nested <fileset/>s.
c.. In the <taskdef/> you have to specify the classpath to include
both this task as well as the jars of the plugins I mentioned in the earlier
mail.
d.. The task supports the "class" attribute (FQCN) which overloads the
JET directives "class" and "package" in the template. It can also be used if
the JET directive is missing altogether. I added this attribute because
sometimes I want to specify the class to generate outside the template.
(This attribute of course doesn't make any sense if the task is enhanced to
work with whole <fileset/>s.)
Here's a simple Ant buildfile (the taskdef classpath assumes you have
Eclipse 2.1 and EMF 1.1.0):
<project default="jetc">
<property name="eclipse.plugins.dir"
location="C:/Products/eclipse-2.1/plugins"/>
<taskdef name="jetc" classname="ch.paranor.epla.structure.JETCTask">
<classpath>
<pathelement location="jetc-task.jar"/>
<fileset dir="${eclipse.plugins.dir}">
<include name="org.eclipse.core.boot_2.1.0/boot.jar"/>
<include name="org.eclipse.core.resources_2.1.0/resources.jar"/>
<include name="org.eclipse.core.runtime_2.1.0/runtime.jar"/>
<include name="org.eclipse.emf.codegen_1.1.0/runtime/codegen.jar"/>
<include name="org.eclipse.jdt.core_2.1.0/jdtcore.jar"/>
</fileset>
</classpath>
</taskdef>
<target name="jetc">
<jetc template="test.xmljet" class="com.foo.Test" destdir="."/>
</target>
</project>
Hope you can work with this! And be sure to notify me of any
improvements you make! :-)
--
knut
"Remko Popma" <remko.popma@azzurri.jp> wrote in message
news:baubb1$tj7$1@rogue.oti.com...
Knut,
I'm definitely interested. Can you post it here or send it to me by
email?
Thanks.
Remko
"Knut Wannheden" <knut.wannheden@paranor.ch> wrote in message
news:batn96$hf6$1@rogue.oti.com...
Great!
I've been using JET in a standalone application for some time now.
But I'm not using dynamic templates, so I precompile the templates inside
Eclipse first and then use them in the standalone application, where no JET
runtime is required anymore. I actually also wrote a simple Ant task to
compile the JET templates outside Eclipse. I then compile the generated
source using Ant's usual <javac/> and can load the class with reflection.
But it never occured to me that maybe JETEmitter could be used. I'll have
to investigate that.
Note on the Ant task: To get it to work I need the jars of the
following plugins on the classpath: org.eclipse.core.boot,
org.eclipse.core.runtime, org.eclipse.core.resources, org.eclipse.jdt.core,
and org.eclipse.emf.codegen. This is rather a lot... But if anyone is
interested I'd be happy to send the Ant task.
--
knut
------=_NextPart_000_02A0_01C32642.7B7925E0
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content=3D"text/html; charset=3Diso-8859-1" =
http-equiv=3DContent-Type>
<META content=3D"MSHTML 5.00.2920.0" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Finally had a chance =
to have a look. Very=20
nice!</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Your task and =
JEmitter seem to have a lot of=20
similarities,</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>with some subtle =
differences. Calling generate=20
on a JEmitter</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>will do the =
compilation and always invoke a=20
method on the generated</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>class file. Your =
class allows you to store the=20
intermediate java and or</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>class files, and call =
these classes=20
later.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>The biggest =
difference is that your task can=20
be used outside of Eclipse,</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>as long as the jar =
files you mentioned are on=20
the classpath, right? That's very handy.</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>JETEmitter can only =
be used inside Eclipse=20
(plugins must be initialized).</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>JETCompiler only =
refers to the plugin to get=20
localized error messages</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>if an exception =
occurs, so as long as your=20
pre-checking is strict enough</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>that no errors occur =
you should be=20
ok.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Thanks for sharing =
the code!</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Remko</FONT></DIV>
<DIV> </DIV>
<BLOCKQUOTE dir=3Dltr=20
style=3D"BORDER-LEFT: #000000 2px solid; MARGIN-LEFT: 5px; MARGIN-RIGHT: =
0px; PADDING-LEFT: 5px; PADDING-RIGHT: 0px">
<DIV>"Knut Wannheden" <<A=20
=
href=3D"mailto:knut.wannheden@paranor.ch">knut.wannheden@paranor.ch</A>&g=
t;=20
wrote in message <A=20
=
href=3D"news:bb2khn$7oj$1@rogue.oti.com">news:bb2khn$7oj$1@rogue.oti.com<=
/A>...</DIV>
<DIV><FONT face=3DArial size=3D2>Couldn't keep my self from adding=20
<fileset/> support :-)</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Now you can either use the attribute =
"template"=20
(optionally in conjunction with "package" and/or "class") or nested=20
<fileset/>s. But not both!</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Also I removed the part that invokes=20
<javac/>. So now you have to do that separately in the=20
buildfile. Example (compiles all JET templates in =
"jet-templates" to=20
"classes" and deletes the temporary directory used for java=20
sources):</FONT></DIV>
<BLOCKQUOTE dir=3Dltr style=3D"MARGIN-RIGHT: 0px">
<DIV><FONT face=3D"Courier New" size=3D2> <target=20
name=3D"jetc"></FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2> <mkdir=20
dir=3D"jet-output"/><BR> <jetc=20
destdir=3D"jet-output"><BR> <fileset =
dir=3D"jet-templates"=20
includes=3D"*.*jet"/><BR> </jetc><BR> <javac =
srcdir=3D"jet-output" destdir=3D"classes"/><BR> <delete=20
=
dir=3D"jet-output"/><BR> </target> </FONT></DIV></BLOCKQUOTE=
>
<DIV dir=3Dltr><FONT face=3DArial size=3D2>Cheers,</FONT></DIV>
<DIV dir=3Dltr><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV dir=3Dltr><FONT face=3DArial size=3D2>--</FONT></DIV>
<DIV dir=3Dltr><FONT face=3DArial size=3D2>knut</FONT></DIV>
<BLOCKQUOTE dir=3Dltr=20
style=3D"BORDER-LEFT: #000000 2px solid; MARGIN-LEFT: 5px; =
MARGIN-RIGHT: 0px; PADDING-LEFT: 5px; PADDING-RIGHT: 0px">
<DIV>"Knut Wannheden" <<A=20
=
href=3D"mailto:knut.wannheden@paranor.ch">knut.wannheden@paranor.ch</A>&g=
t;=20
wrote in message <A=20
=
href=3D"news:bb2f2o$23i$1@rogue.oti.com">news:bb2f2o$23i$1@rogue.oti.com<=
/A>...</DIV>
<DIV><FONT face=3DArial size=3D2>Remko,</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Here you go (source and =
jar)!</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Some notes:</FONT></DIV>
<UL>
<LI><FONT face=3DArial size=3D2>The task both runs the JET =
compiler and Ant's=20
<javac/>, so the final result is a .class file. But =
it's easy=20
to change so it only performs the first step.</FONT>=20
<LI><FONT face=3DArial size=3D2>The task only handles a single =
template at the=20
time. An obvious and simple improvment would be to make the task=20
handle nested <fileset/>s.</FONT>=20
<LI><FONT face=3DArial size=3D2>In the <taskdef/> you have =
to specify=20
the classpath to include both this task as well as the jars of the =
plugins=20
I mentioned in the earlier mail.</FONT>=20
<LI><FONT face=3DArial size=3D2>The task supports the "class" =
attribute (FQCN)=20
which overloads the JET directives "class" and "package" in the =
template.=20
It can also be used if the JET directive is missing altogether. I =
added=20
this attribute because sometimes I want to specify the class to =
generate=20
outside the template. (This attribute of course doesn't make =
any=20
sense if the task is enhanced to work with whole=20
<fileset/>s.)</FONT></LI></UL>
<DIV><FONT face=3DArial size=3D2>Here's a simple Ant buildfile (the =
taskdef=20
classpath assumes you have Eclipse 2.1 and EMF 1.1.0):</FONT></DIV>
<BLOCKQUOTE dir=3Dltr style=3D"MARGIN-RIGHT: 0px">
<DIV><FONT face=3D"Courier New" size=3D2><project=20
default=3D"jetc"></FONT></DIV>
<DIV><FONT face=3D"Courier New"></FONT> </DIV>
<DIV><FONT face=3D"Courier New" size=3D2> <property=20
name=3D"eclipse.plugins.dir"=20
location=3D"C:/Products/eclipse-2.1/plugins"/></FONT ></DIV>
<DIV><FONT face=3D"Courier New"></FONT> </DIV>
<DIV><FONT face=3D"Courier New" size=3D2> <taskdef =
name=3D"jetc"=20
classname=3D"ch.paranor.epla.structure.JETCTask"><BR > =20
<classpath><BR> <pathelement=20
location=3D"jetc-task.jar"/><BR> <fileset=20
dir=3D"${eclipse.plugins.dir}"><BR> <include=20
name=3D"org.eclipse.core.boot_2.1.0/boot.jar"/><BR > =
<include=20
=
name=3D"org.eclipse.core.resources_2.1.0/resources.jar"/> <BR> &nb=
sp;=20
<include=20
=
name=3D"org.eclipse.core.runtime_2.1.0/runtime.jar"/> <BR> =
<include=20
=
name=3D"org.eclipse.emf.codegen_1.1.0/runtime/codegen.jar"/> <BR> =
=20
<include =
name=3D"org.eclipse.jdt.core_2.1.0/jdtcore.jar"/><BR > =20
=
</fileset><BR> </classpath> <BR> </taskdef></F=
ONT></DIV>
<DIV><FONT face=3D"Courier New"></FONT> </DIV>
<DIV><FONT face=3D"Courier New" size=3D2> <target=20
name=3D"jetc"><BR> <jetc template=3D"test.xmljet"=20
class=3D"com.foo.Test"=20
destdir=3D"."/><BR> </target> </FONT></DIV>
<DIV><FONT face=3D"Courier New"></FONT> </DIV>
<DIV dir=3Dltr><FONT face=3D"Courier New"=20
size=3D2></project></FONT></DIV></BLOCKQUOTE >
<DIV dir=3Dltr><FONT face=3DArial size=3D2>Hope you can work with =
this! And=20
be sure to notify me of any improvements you make! :-)</FONT></DIV>
<DIV dir=3Dltr><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV dir=3Dltr><FONT face=3DArial size=3D2>--</FONT></DIV>
<DIV dir=3Dltr><FONT face=3DArial size=3D2>knut</FONT></DIV>
<BLOCKQUOTE dir=3Dltr=20
style=3D"BORDER-LEFT: #000000 2px solid; MARGIN-LEFT: 5px; =
MARGIN-RIGHT: 0px; PADDING-LEFT: 5px; PADDING-RIGHT: 0px">
<DIV>"Remko Popma" <<A=20
=
href=3D"mailto:remko.popma@azzurri.jp">remko.popma@azzurri.jp</A>> =
wrote=20
in message <A=20
=
href=3D"news:baubb1$tj7$1@rogue.oti.com">news:baubb1$tj7$1@rogue.oti.com<=
/A>...</DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Knut,</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>I'm definitely =
interested. Can you post=20
it here or send it to me by email?</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Thanks.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Remko</FONT></DIV>
<DIV> </DIV>
<BLOCKQUOTE dir=3Dltr=20
style=3D"BORDER-LEFT: #000000 2px solid; MARGIN-LEFT: 5px; =
MARGIN-RIGHT: 0px; PADDING-LEFT: 5px; PADDING-RIGHT: 0px">
<DIV>"Knut Wannheden" <<A=20
=
href=3D"mailto:knut.wannheden@paranor.ch">knut.wannheden@paranor.ch</A>&g=
t;=20
wrote in message <A=20
=
href=3D"news:batn96$hf6$1@rogue.oti.com">news:batn96$hf6$1@rogue.oti.com<=
/A>...</DIV>
<DIV>
<DIV><FONT face=3DArial size=3D2>Great!</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>I've been using JET in a =
standalone=20
application for some time now. But I'm not using dynamic=20
templates, so I precompile the templates inside Eclipse first =
and then=20
use them in the standalone application, where no JET runtime is =
required=20
anymore. I actually also wrote a simple Ant task to =
compile the=20
JET templates outside Eclipse. I then compile the =
generated source=20
using Ant's usual <javac/> and can load the class with=20
reflection. But it never occured to me that maybe =
JETEmitter could=20
be used. I'll have to investigate that.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Note on the Ant task: To get it =
to work I=20
need the jars of the following plugins on the classpath:=20
org.eclipse.core.boot, org.eclipse.core.runtime,=20
org.eclipse.core.resources, org.eclipse.jdt.core, and=20
org.eclipse.emf.codegen. This is rather a lot... But =
if=20
anyone is interested I'd be happy to send the Ant =
task.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>--</FONT></DIV>
<DIV><FONT face=3DArial=20
=
size=3D2>knut</FONT></DIV></DIV></BLOCKQUOTE></BLOCKQUOTE ></BLOCKQUOTE></=
BLOCKQUOTE></BODY></HTML>
------=_NextPart_000_02A0_01C32642.7B7925E0--
|
|
|
| Re: getting started with JETEmitter [message #377676 is a reply to message #377661] |
Mon, 02 June 2003 07:10   |
Knut Wannheden Messages: 283 Registered: July 2009 |
Senior Member |
|
|
This is a multi-part message in MIME format.
------=_NextPart_000_000D_01C32908.579BEEA0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Remko,
As you noticed the purpose of the task is to compile JET templates =
outside Eclipse. The reason being that I am using JET for entirely =
different purposes than EMF. Instantiating the compiled templates is =
fairly easy with reflection. It only requires something like:
Class emitterClass =3D =
getClass().getClassLoader().loadClass("com.foo.ABC");
Method m =3D emitterClass.getDeclaredMethod("generate", new Class[] { =
Object.class });
String instantiatedTemplate =3D =
m.invoke(m.getDeclaringClass().newInstance(), new Object[] { someObject =
});
And for this part there are no runtime dependecies on JET or any other =
part of Eclipse. That is also part of the motivation for this task, as =
the dependencies for compiling templates are quite extensive. I think =
it would be nice if JET were a little bit more self contained in this =
respect.
--
knut
"Remko Popma" <remko.popma@azzurri.jp> wrote in message =
news:bb5922$51f$1@rogue.oti.com...
Finally had a chance to have a look. Very nice!
Your task and JEmitter seem to have a lot of similarities,
with some subtle differences. Calling generate on a JEmitter
will do the compilation and always invoke a method on the generated
class file. Your class allows you to store the intermediate java and =
or
class files, and call these classes later.
The biggest difference is that your task can be used outside of =
Eclipse,
as long as the jar files you mentioned are on the classpath, right? =
That's very handy.
JETEmitter can only be used inside Eclipse (plugins must be =
initialized).
JETCompiler only refers to the plugin to get localized error messages
if an exception occurs, so as long as your pre-checking is strict =
enough
that no errors occur you should be ok.
Thanks for sharing the code!
Remko
"Knut Wannheden" <knut.wannheden@paranor.ch> wrote in message =
news:bb2khn$7oj$1@rogue.oti.com...
Couldn't keep my self from adding <fileset/> support :-)
Now you can either use the attribute "template" (optionally in =
conjunction with "package" and/or "class") or nested <fileset/>s. But =
not both!
Also I removed the part that invokes <javac/>. So now you have to =
do that separately in the buildfile. Example (compiles all JET =
templates in "jet-templates" to "classes" and deletes the temporary =
directory used for java sources):
<target name=3D"jetc">
<mkdir dir=3D"jet-output"/>
<jetc destdir=3D"jet-output">
<fileset dir=3D"jet-templates" includes=3D"*.*jet"/>
</jetc>
<javac srcdir=3D"jet-output" destdir=3D"classes"/>
<delete dir=3D"jet-output"/>
</target>
Cheers,
--
knut
"Knut Wannheden" <knut.wannheden@paranor.ch> wrote in message =
news:bb2f2o$23i$1@rogue.oti.com...
Remko,
Here you go (source and jar)!
Some notes:
a.. The task both runs the JET compiler and Ant's <javac/>, so =
the final result is a .class file. But it's easy to change so it only =
performs the first step.=20
b.. The task only handles a single template at the time. An =
obvious and simple improvment would be to make the task handle nested =
<fileset/>s.=20
c.. In the <taskdef/> you have to specify the classpath to =
include both this task as well as the jars of the plugins I mentioned in =
the earlier mail.=20
d.. The task supports the "class" attribute (FQCN) which =
overloads the JET directives "class" and "package" in the template. It =
can also be used if the JET directive is missing altogether. I added =
this attribute because sometimes I want to specify the class to generate =
outside the template. (This attribute of course doesn't make any sense =
if the task is enhanced to work with whole <fileset/>s.)
Here's a simple Ant buildfile (the taskdef classpath assumes you =
have Eclipse 2.1 and EMF 1.1.0):
<project default=3D"jetc">
<property name=3D"eclipse.plugins.dir" =
location=3D"C:/Products/eclipse-2.1/plugins"/>
<taskdef name=3D"jetc" =
classname=3D"ch.paranor.epla.structure.JETCTask">
<classpath>
<pathelement location=3D"jetc-task.jar"/>
<fileset dir=3D"${eclipse.plugins.dir}">
<include name=3D"org.eclipse.core.boot_2.1.0/boot.jar"/>
<include =
name=3D"org.eclipse.core.resources_2.1.0/resources.jar"/>
<include =
name=3D"org.eclipse.core.runtime_2.1.0/runtime.jar"/>
<include =
name=3D"org.eclipse.emf.codegen_1.1.0/runtime/codegen.jar"/ >
<include name=3D"org.eclipse.jdt.core_2.1.0/jdtcore.jar"/>
</fileset>
</classpath>
</taskdef>
<target name=3D"jetc">
<jetc template=3D"test.xmljet" class=3D"com.foo.Test" =
destdir=3D"."/>
</target>
</project>
Hope you can work with this! And be sure to notify me of any =
improvements you make! :-)
--
knut
"Remko Popma" <remko.popma@azzurri.jp> wrote in message =
news:baubb1$tj7$1@rogue.oti.com...
Knut,
I'm definitely interested. Can you post it here or send it to me =
by email?
Thanks.
Remko
"Knut Wannheden" <knut.wannheden@paranor.ch> wrote in message =
news:batn96$hf6$1@rogue.oti.com...
Great!
I've been using JET in a standalone application for some time =
now. But I'm not using dynamic templates, so I precompile the templates =
inside Eclipse first and then use them in the standalone application, =
where no JET runtime is required anymore. I actually also wrote a =
simple Ant task to compile the JET templates outside Eclipse. I then =
compile the generated source using Ant's usual <javac/> and can load the =
class with reflection. But it never occured to me that maybe JETEmitter =
could be used. I'll have to investigate that.
Note on the Ant task: To get it to work I need the jars of the =
following plugins on the classpath: org.eclipse.core.boot, =
org.eclipse.core.runtime, org.eclipse.core.resources, =
org.eclipse.jdt.core, and org.eclipse.emf.codegen. This is rather a =
lot... But if anyone is interested I'd be happy to send the Ant task.
--
knut
------=_NextPart_000_000D_01C32908.579BEEA0
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.2800.1170" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3DArial size=3D2>Remko,</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>As you noticed the purpose of the task =
is to=20
compile JET templates outside Eclipse. The reason being that I am =
using=20
JET for entirely different purposes than EMF. Instantiating the =
compiled=20
templates is fairly easy with reflection. It only requires =
something=20
like:</FONT></DIV>
<BLOCKQUOTE dir=3Dltr style=3D"MARGIN-RIGHT: 0px">
<DIV><FONT size=3D2>
<P><FONT face=3D"Courier New">Class emitterClass =3D=20
getClass().getClassLoader().loadClass(<FONT=20
color=3D#2a00ff>"com.foo.ABC"</FONT><FONT color=3D#000000>);<BR>Method =
m =3D=20
emitterClass.getDeclaredMethod(</FONT></FONT></FONT><FONT=20
face=3D"Courier New"><FONT size=3D2><FONT color=3D#2a00ff=20
size=3D2>"generate"</FONT></FONT><FONT size=3D2>, </FONT><B><FONT=20
size=3D2>new</B></FONT></FONT><FONT face=3D"Courier New"><FONT =
size=3D2> Class[] {=20
Object.</FONT><B><FONT size=3D2>class</B></FONT></FONT><FONT=20
face=3D"Courier New"><FONT size=3D2> });<BR></FONT></FONT><FONT=20
face=3D"Courier New"><FONT size=3D2>String instantiatedTemplate=20
=3D m.invoke(m.getDeclaringClass().newInstance(), </FONT><B><FONT =
size=3D2>new</B></FONT></FONT><FONT size=3D2><FONT face=3D"Courier =
New"> Object[] {=20
someObject });</FONT></FONT></P></DIV></BLOCKQUOTE>
<P dir=3Dltr><FONT size=3D2><FONT face=3DArial>And for this part there =
are no runtime=20
dependecies on JET or any other part of Eclipse. That is also part =
of the=20
motivation for this task, as the dependencies for compiling templates =
are quite=20
extensive. I think it would be nice if JET were a little bit more =
self=20
contained in this respect.</FONT></FONT></P>
<P dir=3Dltr><FONT size=3D2><FONT =
face=3DArial>--<BR>knut</FONT></P></FONT>
<BLOCKQUOTE dir=3Dltr=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
<DIV>"Remko Popma" <<A=20
href=3D"mailto:remko.popma@azzurri.jp">remko.popma@azzurri.jp</A>> =
wrote in=20
message <A=20
=
href=3D"news:bb5922$51f$1@rogue.oti.com">news:bb5922$51f$1@rogue.oti.com<=
/A>...</DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Finally had a chance =
to have a look. Very=20
nice!</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Your task and =
JEmitter seem to have a lot of=20
similarities,</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>with some subtle =
differences. Calling=20
generate on a JEmitter</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>will do the =
compilation and always invoke a=20
method on the generated</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>class file. Your =
class allows you to store=20
the intermediate java and or</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>class files, and call =
these classes=20
later.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>The biggest =
difference is that your task can=20
be used outside of Eclipse,</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>as long as the jar =
files you mentioned are=20
on the classpath, right? That's very handy.</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>JETEmitter can only =
be used inside Eclipse=20
(plugins must be initialized).</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>JETCompiler only =
refers to the plugin to get=20
localized error messages</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>if an exception =
occurs, so as long as your=20
pre-checking is strict enough</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>that no errors occur =
you should be=20
ok.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Thanks for sharing =
the code!</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Remko</FONT></DIV>
<DIV> </DIV>
<BLOCKQUOTE dir=3Dltr=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
<DIV>"Knut Wannheden" <<A=20
=
href=3D"mailto:knut.wannheden@paranor.ch">knut.wannheden@paranor.ch</A>&g=
t;=20
wrote in message <A=20
=
href=3D"news:bb2khn$7oj$1@rogue.oti.com">news:bb2khn$7oj$1@rogue.oti.com<=
/A>...</DIV>
<DIV><FONT face=3DArial size=3D2>Couldn't keep my self from adding=20
<fileset/> support :-)</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Now you can either use the =
attribute "template"=20
(optionally in conjunction with "package" and/or "class") or nested=20
<fileset/>s. But not both!</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Also I removed the part that =
invokes=20
<javac/>. So now you have to do that separately in the=20
buildfile. Example (compiles all JET templates in =
"jet-templates" to=20
"classes" and deletes the temporary directory used for java=20
sources):</FONT></DIV>
<BLOCKQUOTE dir=3Dltr style=3D"MARGIN-RIGHT: 0px">
<DIV><FONT face=3D"Courier New" size=3D2> <target=20
name=3D"jetc"></FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2> <mkdir=20
dir=3D"jet-output"/><BR> <jetc=20
destdir=3D"jet-output"><BR> <fileset =
dir=3D"jet-templates"=20
includes=3D"*.*jet"/><BR> </jetc><BR> =
<javac=20
srcdir=3D"jet-output" destdir=3D"classes"/><BR> =
<delete=20
=
dir=3D"jet-output"/><BR> </target> </FONT></DIV></BLOCKQUOTE=
>
<DIV dir=3Dltr><FONT face=3DArial size=3D2>Cheers,</FONT></DIV>
<DIV dir=3Dltr><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV dir=3Dltr><FONT face=3DArial size=3D2>--</FONT></DIV>
<DIV dir=3Dltr><FONT face=3DArial size=3D2>knut</FONT></DIV>
<BLOCKQUOTE dir=3Dltr=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
<DIV>"Knut Wannheden" <<A=20
=
href=3D"mailto:knut.wannheden@paranor.ch">knut.wannheden@paranor.ch</A>&g=
t;=20
wrote in message <A=20
=
href=3D"news:bb2f2o$23i$1@rogue.oti.com">news:bb2f2o$23i$1@rogue.oti.com<=
/A>...</DIV>
<DIV><FONT face=3DArial size=3D2>Remko,</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Here you go (source and =
jar)!</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Some notes:</FONT></DIV>
<UL>
<LI><FONT face=3DArial size=3D2>The task both runs the JET =
compiler and=20
Ant's <javac/>, so the final result is a .class =
file. But=20
it's easy to change so it only performs the first step.</FONT>=20
<LI><FONT face=3DArial size=3D2>The task only handles a single =
template at=20
the time. An obvious and simple improvment would be to make the =
task=20
handle nested <fileset/>s.</FONT>=20
<LI><FONT face=3DArial size=3D2>In the <taskdef/> you have =
to specify=20
the classpath to include both this task as well as the jars of =
the=20
plugins I mentioned in the earlier mail.</FONT>=20
<LI><FONT face=3DArial size=3D2>The task supports the "class" =
attribute=20
(FQCN) which overloads the JET directives "class" and "package" =
in the=20
template. It can also be used if the JET directive is missing=20
altogether. I added this attribute because sometimes I want to =
specify=20
the class to generate outside the template. (This =
attribute of=20
course doesn't make any sense if the task is enhanced to work =
with whole=20
<fileset/>s.)</FONT></LI></UL>
<DIV><FONT face=3DArial size=3D2>Here's a simple Ant buildfile =
(the taskdef=20
classpath assumes you have Eclipse 2.1 and EMF =
1.1.0):</FONT></DIV>
<BLOCKQUOTE dir=3Dltr style=3D"MARGIN-RIGHT: 0px">
<DIV><FONT face=3D"Courier New" size=3D2><project=20
default=3D"jetc"></FONT></DIV>
<DIV><FONT face=3D"Courier New"></FONT> </DIV>
<DIV><FONT face=3D"Courier New" size=3D2> <property=20
name=3D"eclipse.plugins.dir"=20
location=3D"C:/Products/eclipse-2.1/plugins"/></FONT ></DIV>
<DIV><FONT face=3D"Courier New"></FONT> </DIV>
<DIV><FONT face=3D"Courier New" size=3D2> <taskdef =
name=3D"jetc"=20
classname=3D"ch.paranor.epla.structure.JETCTask"><BR > =20
<classpath><BR> <pathelement=20
location=3D"jetc-task.jar"/><BR> <fileset=20
dir=3D"${eclipse.plugins.dir}"><BR> <include=20
=
name=3D"org.eclipse.core.boot_2.1.0/boot.jar"/><BR > =20
<include=20
=
name=3D"org.eclipse.core.resources_2.1.0/resources.jar"/> <BR> &nb=
sp;=20
<include=20
=
name=3D"org.eclipse.core.runtime_2.1.0/runtime.jar"/> <BR> =
<include=20
=
name=3D"org.eclipse.emf.codegen_1.1.0/runtime/codegen.jar"/> <BR> =
=20
<include =
name=3D"org.eclipse.jdt.core_2.1.0/jdtcore.jar"/><BR > =20
=
</fileset><BR> </classpath> <BR> </taskdef></F=
ONT></DIV>
<DIV><FONT face=3D"Courier New"></FONT> </DIV>
<DIV><FONT face=3D"Courier New" size=3D2> <target=20
name=3D"jetc"><BR> <jetc template=3D"test.xmljet"=20
class=3D"com.foo.Test"=20
destdir=3D"."/><BR> </target> </FONT></DIV>
<DIV><FONT face=3D"Courier New"></FONT> </DIV>
<DIV dir=3Dltr><FONT face=3D"Courier New"=20
size=3D2></project></FONT></DIV></BLOCKQUOTE >
<DIV dir=3Dltr><FONT face=3DArial size=3D2>Hope you can work with =
this! =20
And be sure to notify me of any improvements you make! =
:-)</FONT></DIV>
<DIV dir=3Dltr><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV dir=3Dltr><FONT face=3DArial size=3D2>--</FONT></DIV>
<DIV dir=3Dltr><FONT face=3DArial size=3D2>knut</FONT></DIV>
<BLOCKQUOTE dir=3Dltr=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
<DIV>"Remko Popma" <<A=20
=
href=3D"mailto:remko.popma@azzurri.jp">remko.popma@azzurri.jp</A>>=20
wrote in message <A=20
=
href=3D"news:baubb1$tj7$1@rogue.oti.com">news:baubb1$tj7$1@rogue.oti.com<=
/A>...</DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Knut,</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>I'm definitely =
interested. Can you=20
post it here or send it to me by email?</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Thanks.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Remko</FONT></DIV>
<DIV> </DIV>
<BLOCKQUOTE dir=3Dltr=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: =
5px; BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
<DIV>"Knut Wannheden" <<A=20
=
href=3D"mailto:knut.wannheden@paranor.ch">knut.wannheden@paranor.ch</A>&g=
t;=20
wrote in message <A=20
=
href=3D"news:batn96$hf6$1@rogue.oti.com">news:batn96$hf6$1@rogue.oti.com<=
/A>...</DIV>
<DIV>
<DIV><FONT face=3DArial size=3D2>Great!</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>I've been using JET in a =
standalone=20
application for some time now. But I'm not using dynamic =
templates, so I precompile the templates inside Eclipse first =
and then=20
use them in the standalone application, where no JET runtime =
is=20
required anymore. I actually also wrote a simple Ant =
task to=20
compile the JET templates outside Eclipse. I then =
compile the=20
generated source using Ant's usual <javac/> and can load =
the=20
class with reflection. But it never occured to me that =
maybe=20
JETEmitter could be used. I'll have to investigate=20
that.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Note on the Ant task: To get =
it to work I=20
need the jars of the following plugins on the classpath:=20
org.eclipse.core.boot, org.eclipse.core.runtime,=20
org.eclipse.core.resources, org.eclipse.jdt.core, and=20
org.eclipse.emf.codegen. This is rather a lot... =
But if=20
anyone is interested I'd be happy to send the Ant =
task.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>--</FONT></DIV>
<DIV><FONT face=3DArial=20
=
size=3D2>knut</FONT></DIV></DIV></BLOCKQUOTE></BLOCKQUOTE ></BLOCKQUOTE></=
BLOCKQUOTE></BLOCKQUOTE></BODY></HTML>
------=_NextPart_000_000D_01C32908.579BEEA0--
|
|
|
| Re: getting started with JETEmitter [message #377767 is a reply to message #377676] |
Thu, 05 June 2003 16:24   |
|
Originally posted by: remko.popma.azzurri.jp
This is a multi-part message in MIME format.
------=_NextPart_000_03D7_01C32BEB.E234DCD0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Knut,
Did you know that you can make the java classes generated from a JET
template implement an interface?
That way you can avoid using reflection, and instead have code that looks
like this:
Class emitterClass = getClass().getClassLoader().loadClass("com.foo.ABC");
IMyInterface template = (IMyInterface) emitterClass.newInstance();
String result = template.generate(someObject);
In each JET template file, modify the JET directive (on the first line) to
have a skeleton attribute.
For example:
<%@ jet package="com.foo" class="ABC" skeleton="jet_template.skeleton" %>
In the same directory as the JET template files, create a file called
jet_template.skeleton
with the following content:
public class CLASS implements com.foo.stuff.IMyInterface {
/*
* (Non-javadoc)
* @see com.foo.stuff.IMyInterface#generate(Object)
*/
public String generate(Object argument) {
return "";
}
}
Another neat feature is that you can change the tags that mark scriptlets in
the template
with the startTag and endTag attributes (also in the JET directive on the
first line of the template).
This is very convenient if you want to generate source code for JSP pages.
For example:
<%@ jet package="com.foo" class="JspTemplate" startTag="<$" endTag="$>" %>
<$ String message = (String) argument; /* This is an executed scriptlet */
$>
<$ if (message != null) { $>
<%= request.getParameter("<$=message$>") %> <!-- this is generated JSP -->
<$ } $>
"Knut Wannheden" <knut.wannheden@paranor.ch> wrote in message
news:bbfbb7$cg1$1@rogue.oti.com...
Remko,
As you noticed the purpose of the task is to compile JET templates outside
Eclipse. The reason being that I am using JET for entirely different
purposes than EMF. Instantiating the compiled templates is fairly easy with
reflection. It only requires something like:
Class emitterClass =
getClass().getClassLoader().loadClass("com.foo.ABC");
Method m = emitterClass.getDeclaredMethod("generate", new Class[]
Object.class });
String instantiatedTemplate =
m.invoke(m.getDeclaringClass().newInstance(), new Object[] { someObject });
And for this part there are no runtime dependecies on JET or any other
part of Eclipse. That is also part of the motivation for this task, as the
dependencies for compiling templates are quite extensive. I think it would
be nice if JET were a little bit more self contained in this respect.
--
knut
------=_NextPart_000_03D7_01C32BEB.E234DCD0
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content=3D"text/html; charset=3Diso-8859-1" =
http-equiv=3DContent-Type>
<META content=3D"MSHTML 5.00.2920.0" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Knut,</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Did you know that you =
can make the java=20
classes generated from a JET template implement an =
interface?</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>That way you can =
avoid using reflection, and=20
instead have code that looks like this:</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2><FONT face=3D"Courier =
New">Class emitterClass =3D=20
getClass().getClassLoader().loadClass(<FONT=20
color=3D#2a00ff>"com.foo.ABC"</FONT><FONT=20
color=3D#000000>);</FONT></FONT></FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2><FONT face=3D"Courier =
New"><FONT=20
color=3D#000000>IMyInterface template =3D (IMyInterface)=20
emitterClass.newInstance();</FONT></FONT></FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2><FONT face=3D"Courier =
New"><FONT=20
color=3D#000000>String result =3D=20
template.generate(someObject);</FONT></FONT></FONT></DIV >
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2><FONT face=3D"Courier =
New"><FONT=20
size=3D2></FONT></FONT></FONT> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2><FONT face=3D"Courier =
New"><FONT size=3D2><FONT=20
face=3D"MS =
Pゴシック "></FONT></FONT></FONT></FONT>&nb=
sp;</DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2><FONT face=3D"Courier =
New"><FONT size=3D2><FONT=20
face=3D"MS Pゴシック ">In =
each JET template file, modify the JET directive (on the=20
first line) to have a <FONT face=3D"Courier New">skeleton</FONT>=20
attribute.</FONT></FONT></FONT></FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2><FONT face=3D"Courier =
New"><FONT size=3D2><FONT=20
face=3D"MS Pゴシック ">For =
example:</FONT></FONT></FONT></FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2><FONT face=3D"Courier =
New"><FONT size=3D2><FONT=20
face=3D"MS =
Pゴシック "></FONT></FONT></FONT></FONT>&nb=
sp;</DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2><FONT size=3D2><FONT =
face=3D"Courier New"><%@=20
jet package=3D"com.foo" class=3D"ABC" skeleton=3D"jet_template.skeleton" =
%><BR></FONT></FONT></FONT></DIV>
<DIV><FONT size=3D2><FONT size=3D2><FONT=20
face=3D"MS =
Pゴシック "></FONT></FONT></FONT> </DI=
V>
<DIV><FONT size=3D2><FONT size=3D2><FONT face=3D"MS =
Pゴシック ">In the same directory as=20
the JET template files, create a file called </FONT><FONT=20
face=3D"Courier New">jet_template.skeleton</FONT></FONT></FONT><FONT =
size=3D2><FONT=20
size=3D2><FONT face=3D"MS =
Pゴシック "> </FONT></FONT></FONT></DIV>
<DIV><FONT size=3D2><FONT size=3D2><FONT face=3D"MS =
Pゴシック ">with the following=20
content:</FONT></FONT></FONT></DIV>
<DIV><FONT size=3D2><FONT size=3D2></FONT></FONT> </DIV>
<DIV><FONT size=3D2><FONT size=3D2><FONT face=3D"Courier New">public =
class CLASS=20
implements com.foo.stuff.<FONT size=3D2><FONT =
color=3D#000000>IMyInterface=20
</FONT></FONT>{<BR> /*<BR> * =
(Non-javadoc)<BR> *=20
@see com.foo.stuff.<FONT size=3D2><FONT=20
color=3D#000000>IMyInterface</FONT></FONT>#generate(Object) <BR> &nbs=
p;=20
*/<BR> public String generate(Object argument) =
{<BR> =20
return "";<BR> }<BR>}<BR></FONT></FONT></FONT></DIV>
<DIV><FONT size=3D2><FONT size=3D2><FONT=20
face=3D"Courier New"></FONT></FONT></FONT> </DIV>
<DIV><FONT size=3D2><FONT size=3D2><FONT face=3D"MS =
Pゴシック ">Another neat feature is=20
that you can change the tags that mark scriptlets in the=20
template</FONT></FONT></FONT></DIV>
<DIV><FONT size=3D2><FONT size=3D2><FONT face=3D"MS =
Pゴシック ">with the <FONT=20
face=3D"Courier New">startTag</FONT> and <FONT face=3D"Courier =
New">endTag</FONT>=20
attributes (also in the JET directive on the first line of the=20
template).</FONT></DIV></FONT></FONT>
<DIV><FONT size=3D2><FONT size=3D2><FONT face=3D"MS =
Pゴシック ">This is very convenient if=20
you want to generate source code for JSP =
pages.</FONT></FONT></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>For =
example:</FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2><%@ jet package=3D"com.foo"=20
class=3D"JspTemplate" startTag=3D"<$" endTag=3D"$>" =
%></FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2><$ String message =3D =
(String) argument;=20
/* This is an executed scriptlet */ $></FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2><$ if (message !=3D null) {=20
$></FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2> <%=3D=20
request.getParameter("<$=3Dmessage$>") %> <!-- this is =
generated JSP=20
--></FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2><$ } $></FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2></FONT> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " =
size=3D2><BR><BR> </DIV></FONT>
<DIV><FONT size=3D2><FONT size=3D2> </DIV></FONT></FONT>
<BLOCKQUOTE dir=3Dltr=20
style=3D"BORDER-LEFT: #000000 2px solid; MARGIN-LEFT: 5px; MARGIN-RIGHT: =
0px; PADDING-LEFT: 5px; PADDING-RIGHT: 0px">
<DIV> </DIV>
<DIV>"Knut Wannheden" <<A=20
=
href=3D"mailto:knut.wannheden@paranor.ch">knut.wannheden@paranor.ch</A>&g=
t;=20
wrote in message <A=20
=
href=3D"news:bbfbb7$cg1$1@rogue.oti.com">news:bbfbb7$cg1$1@rogue.oti.com<=
/A>...</DIV>
<DIV><FONT face=3DArial size=3D2>Remko,</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>As you noticed the purpose of the =
task is to=20
compile JET templates outside Eclipse. The reason being that I =
am using=20
JET for entirely different purposes than EMF. Instantiating the =
compiled=20
templates is fairly easy with reflection. It only requires =
something=20
like:</FONT></DIV>
<BLOCKQUOTE dir=3Dltr style=3D"MARGIN-RIGHT: 0px">
<DIV><FONT size=3D2>
<P><FONT face=3D"Courier New">Class emitterClass =3D=20
getClass().getClassLoader().loadClass(<FONT=20
color=3D#2a00ff>"com.foo.ABC"</FONT><FONT =
color=3D#000000>);<BR>Method m =3D=20
emitterClass.getDeclaredMethod(</FONT></FONT></FONT><FONT=20
face=3D"Courier New"><FONT size=3D2><FONT color=3D#2a00ff=20
size=3D2>"generate"</FONT></FONT><FONT size=3D2>, </FONT><B><FONT=20
size=3D2>new</B></FONT></FONT><FONT face=3D"Courier New"><FONT =
size=3D2> Class[] {=20
Object.</FONT><B><FONT size=3D2>class</B></FONT></FONT><FONT=20
face=3D"Courier New"><FONT size=3D2> });<BR></FONT></FONT><FONT=20
face=3D"Courier New"><FONT size=3D2>String instantiatedTemplate=20
=3D m.invoke(m.getDeclaringClass().newInstance(), =
</FONT><B><FONT=20
size=3D2>new</B></FONT></FONT><FONT size=3D2><FONT face=3D"Courier =
New"> Object[]=20
{ someObject });</FONT></FONT></P></DIV></BLOCKQUOTE>
<P dir=3Dltr><FONT size=3D2><FONT face=3DArial>And for this part there =
are no=20
runtime dependecies on JET or any other part of Eclipse. That is =
also=20
part of the motivation for this task, as the dependencies for =
compiling=20
templates are quite extensive. I think it would be nice if JET =
were a=20
little bit more self contained in this respect.</FONT></FONT></P>
<P dir=3Dltr><FONT size=3D2><FONT=20
face=3DArial>--<BR>knut</FONT></P></FONT></BLOCKQUOTE ></BODY></HTML>
------=_NextPart_000_03D7_01C32BEB.E234DCD0--
|
|
|
| Re: getting started with JETEmitter [message #377825 is a reply to message #377767] |
Tue, 10 June 2003 03:13   |
Knut Wannheden Messages: 283 Registered: July 2009 |
Senior Member |
|
|
This is a multi-part message in MIME format.
------=_NextPart_000_000A_01C32F30.7D6E6B70
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Remko,
Well, you're still using reflection to create an instance of the =
template emitter, no? But it actually implements an interface, so you =
don't have to use reflection to call the generate method. And I assume =
you can even let it extend a class and add additional methods to the =
skeleton. And that can indeed be very handy I suppose. Then you can =
hide some of the flow control and template logic in the skeleton. I'll =
give it a shot. But my template chain just keeps growing... The =
template I instantiate with JET is actually a template again, for an Ant =
buildfile in my case. So it's getting pretty confusing :-)
The startTag and endTag are nice indeed. At first I wanted to use a =
different templating engine then JET, like Velocity for instance. The =
main reason being that they're a little bit more self-contained, better =
documented, and easier to use. But there I had the problem that I had =
to do cumbersome escaping in the template, because the template syntax =
conflicted with what I actually wanted to generate. I wish those =
template engines had a similar feature...
Thanks again for the tips! Seems like you know JET well enough that you =
could write a user's guide for it :-)
--
knut
"Remko Popma" <remko.popma@azzurri.jp> wrote in message =
news:bbo90c$n8b$1@rogue.oti.com...
Knut,
Did you know that you can make the java classes generated from a JET =
template implement an interface?
That way you can avoid using reflection, and instead have code that =
looks like this:
Class emitterClass =3D =
getClass().getClassLoader().loadClass("com.foo.ABC");
IMyInterface template =3D (IMyInterface) emitterClass.newInstance();
String result =3D template.generate(someObject);
In each JET template file, modify the JET directive (on the first =
line) to have a skeleton attribute.
For example:
<%@ jet package=3D"com.foo" class=3D"ABC" =
skeleton=3D"jet_template.skeleton" %>
In the same directory as the JET template files, create a file called =
jet_template.skeleton=20
with the following content:
public class CLASS implements com.foo.stuff.IMyInterface {
/*
* (Non-javadoc)
* @see com.foo.stuff.IMyInterface#generate(Object)
*/
public String generate(Object argument) {
return "";
}
}
Another neat feature is that you can change the tags that mark =
scriptlets in the template
with the startTag and endTag attributes (also in the JET directive on =
the first line of the template).
This is very convenient if you want to generate source code for JSP =
pages.
For example:
<%@ jet package=3D"com.foo" class=3D"JspTemplate" startTag=3D"<$" =
endTag=3D"$>" %>
<$ String message =3D (String) argument; /* This is an executed =
scriptlet */ $>
<$ if (message !=3D null) { $>
<%=3D request.getParameter("<$=3Dmessage$>") %> <!-- this is =
generated JSP -->
<$ } $>
=20
"Knut Wannheden" <knut.wannheden@paranor.ch> wrote in message =
news:bbfbb7$cg1$1@rogue.oti.com...
Remko,
As you noticed the purpose of the task is to compile JET templates =
outside Eclipse. The reason being that I am using JET for entirely =
different purposes than EMF. Instantiating the compiled templates is =
fairly easy with reflection. It only requires something like:
Class emitterClass =3D =
getClass().getClassLoader().loadClass("com.foo.ABC");
Method m =3D emitterClass.getDeclaredMethod("generate", new =
Class[] { Object.class });
String instantiatedTemplate =3D =
m.invoke(m.getDeclaringClass().newInstance(), new Object[] { someObject =
});
And for this part there are no runtime dependecies on JET or any =
other part of Eclipse. That is also part of the motivation for this =
task, as the dependencies for compiling templates are quite extensive. =
I think it would be nice if JET were a little bit more self contained in =
this respect.
--
knut
------=_NextPart_000_000A_01C32F30.7D6E6B70
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.2800.1170" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3DArial size=3D2>Remko,</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Well, you're still using reflection to =
create an=20
instance of the template emitter, no? But it actually implements =
an=20
interface, so you don't have to use reflection to call the generate=20
method. And I assume you can even let it extend a class and add =
additional=20
methods to the skeleton. And that can indeed be very handy I=20
suppose. Then you can hide some of the flow control and template =
logic in=20
the skeleton. I'll give it a shot. But my template chain =
just keeps=20
growing... The template I instantiate with JET is actually a =
template=20
again, for an Ant buildfile in my case. So it's getting pretty =
confusing=20
:-)</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>The startTag and endTag are nice =
indeed. At=20
first I wanted to use a different templating engine then JET, like =
Velocity for=20
instance. The main reason being that they're a little bit more=20
self-contained, better documented, and easier to use. But there I =
had the=20
problem that I had to do cumbersome escaping in the template, because =
the=20
template syntax conflicted with what I actually wanted to =
generate. I wish=20
those template engines had a similar feature...</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Thanks again for the tips! Seems =
like you=20
know JET well enough that you could write a user's guide for it =
:-)</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>--</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>knut</FONT></DIV>
<BLOCKQUOTE dir=3Dltr=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
<DIV>"Remko Popma" <<A=20
href=3D"mailto:remko.popma@azzurri.jp">remko.popma@azzurri.jp</A>> =
wrote in=20
message <A=20
=
href=3D"news:bbo90c$n8b$1@rogue.oti.com">news:bbo90c$n8b$1@rogue.oti.com<=
/A>...</DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Knut,</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>Did you know that you =
can make the java=20
classes generated from a JET template implement an =
interface?</FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>That way you can =
avoid using reflection, and=20
instead have code that looks like this:</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2><FONT face=3D"Courier =
New">Class emitterClass=20
=3D getClass().getClassLoader().loadClass(<FONT=20
color=3D#2a00ff>"com.foo.ABC"</FONT><FONT=20
color=3D#000000>);</FONT></FONT></FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2><FONT face=3D"Courier =
New"><FONT=20
color=3D#000000>IMyInterface template =3D (IMyInterface)=20
emitterClass.newInstance();</FONT></FONT></FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2><FONT face=3D"Courier =
New"><FONT=20
color=3D#000000>String result =3D=20
template.generate(someObject);</FONT></FONT></FONT></DIV >
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2><FONT face=3D"Courier =
New"><FONT=20
size=3D2></FONT></FONT></FONT> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2><FONT face=3D"Courier =
New"><FONT size=3D2><FONT=20
face=3D"MS =
Pゴシック "></FONT></FONT></FONT></FONT>&nb=
sp;</DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2><FONT face=3D"Courier =
New"><FONT size=3D2><FONT=20
face=3D"MS Pゴシック ">In =
each JET template file, modify the JET directive (on the=20
first line) to have a <FONT face=3D"Courier New">skeleton</FONT>=20
attribute.</FONT></FONT></FONT></FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2><FONT face=3D"Courier =
New"><FONT size=3D2><FONT=20
face=3D"MS Pゴシック ">For =
example:</FONT></FONT></FONT></FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2><FONT face=3D"Courier =
New"><FONT size=3D2><FONT=20
face=3D"MS =
Pゴシック "></FONT></FONT></FONT></FONT>&nb=
sp;</DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2><FONT size=3D2><FONT =
face=3D"Courier New"><%@=20
jet package=3D"com.foo" class=3D"ABC" =
skeleton=3D"jet_template.skeleton"=20
%><BR></FONT></FONT></FONT></DIV>
<DIV><FONT size=3D2><FONT size=3D2><FONT=20
face=3D"MS =
Pゴシック "></FONT></FONT></FONT> </DI=
V>
<DIV><FONT size=3D2><FONT size=3D2><FONT face=3D"MS =
Pゴシック ">In the same directory as=20
the JET template files, create a file called </FONT><FONT=20
face=3D"Courier New">jet_template.skeleton</FONT></FONT></FONT><FONT=20
size=3D2><FONT size=3D2><FONT face=3D"MS =
Pゴシック "> </FONT></FONT></FONT></DIV>
<DIV><FONT size=3D2><FONT size=3D2><FONT face=3D"MS =
Pゴシック ">with the following=20
content:</FONT></FONT></FONT></DIV>
<DIV><FONT size=3D2><FONT size=3D2></FONT></FONT> </DIV>
<DIV><FONT size=3D2><FONT size=3D2><FONT face=3D"Courier New">public =
class CLASS=20
implements com.foo.stuff.<FONT size=3D2><FONT =
color=3D#000000>IMyInterface=20
</FONT></FONT>{<BR> /*<BR> * =
(Non-javadoc)<BR> *=20
@see com.foo.stuff.<FONT size=3D2><FONT=20
=
color=3D#000000>IMyInterface</FONT></FONT>#generate(Object) <BR> &nbs=
p;=20
*/<BR> public String generate(Object argument) =
{<BR> =20
return "";<BR> }<BR>}<BR></FONT></FONT></FONT></DIV>
<DIV><FONT size=3D2><FONT size=3D2><FONT=20
face=3D"Courier New"></FONT></FONT></FONT> </DIV>
<DIV><FONT size=3D2><FONT size=3D2><FONT face=3D"MS =
Pゴシック ">Another neat feature is=20
that you can change the tags that mark scriptlets in the=20
template</FONT></FONT></FONT></DIV>
<DIV><FONT size=3D2><FONT size=3D2><FONT face=3D"MS =
Pゴシック ">with the <FONT=20
face=3D"Courier New">startTag</FONT> and <FONT face=3D"Courier =
New">endTag</FONT>=20
attributes (also in the JET directive on the first line of the=20
template).</FONT></DIV></FONT></FONT>
<DIV><FONT size=3D2><FONT size=3D2><FONT face=3D"MS =
Pゴシック ">This is very convenient=20
if you want to generate source code for JSP=20
pages.</FONT></FONT></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2>For =
example:</FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2><%@ jet =
package=3D"com.foo"=20
class=3D"JspTemplate" startTag=3D"<$" endTag=3D"$>" =
%></FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2><$ String message =3D =
(String) argument;=20
/* This is an executed scriptlet */ $></FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2><$ if (message !=3D null) =
{=20
$></FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2> <%=3D=20
request.getParameter("<$=3Dmessage$>") %> <!-- this is =
generated JSP=20
--></FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2><$ } $></FONT></DIV>
<DIV><FONT face=3D"MS =
Pゴシック " size=3D2></FONT> </DIV>
<DIV><FONT face=3D"MS =
Pゴシック " =
size=3D2><BR><BR> </DIV></FONT>
<DIV><FONT size=3D2><FONT size=3D2> </DIV></FONT></FONT>
<BLOCKQUOTE dir=3Dltr=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
<DIV> </DIV>
<DIV>"Knut Wannheden" <<A=20
=
href=3D"mailto:knut.wannheden@paranor.ch">knut.wannheden@paranor.ch</A>&g=
t;=20
wrote in message <A=20
=
href=3D"news:bbfbb7$cg1$1@rogue.oti.com">news:bbfbb7$cg1$1@rogue.oti.com<=
/A>...</DIV>
<DIV><FONT face=3DArial size=3D2>Remko,</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>As you noticed the purpose of the =
task is to=20
compile JET templates outside Eclipse. The reason being that I =
am=20
using JET for entirely different purposes than EMF. =
Instantiating the=20
compiled templates is fairly easy with reflection. It only =
requires=20
something like:</FONT></DIV>
<BLOCKQUOTE dir=3Dltr style=3D"MARGIN-RIGHT: 0px">
<DIV><FONT size=3D2>
<P><FONT face=3D"Courier New">Class emitterClass =3D=20
getClass().getClassLoader().loadClass(<FONT=20
color=3D#2a00ff>"com.foo.ABC"</FONT><FONT =
color=3D#000000>);<BR>Method m =3D=20
emitterClass.getDeclaredMethod(</FONT></FONT></FONT><FONT=20
face=3D"Courier New"><FONT size=3D2><FONT color=3D#2a00ff=20
size=3D2>"generate"</FONT></FONT><FONT size=3D2>, </FONT><B><FONT=20
size=3D2>new</B></FONT></FONT><FONT face=3D"Courier New"><FONT =
size=3D2> Class[]=20
{ Object.</FONT><B><FONT size=3D2>class</B></FONT></FONT><FONT=20
face=3D"Courier New"><FONT size=3D2> });<BR></FONT></FONT><FONT=20
face=3D"Courier New"><FONT size=3D2>String instantiatedTemplate=20
=3D m.invoke(m.getDeclaringClass().newInstance(), =
</FONT><B><FONT=20
size=3D2>new</B></FONT></FONT><FONT size=3D2><FONT face=3D"Courier =
New">=20
Object[] { someObject });</FONT></FONT></P></DIV></BLOCKQUOTE>
<P dir=3Dltr><FONT size=3D2><FONT face=3DArial>And for this part =
there are no=20
runtime dependecies on JET or any other part of Eclipse. That =
is also=20
part of the motivation for this task, as the dependencies for =
compiling=20
templates are quite extensive. I think it would be nice if JET =
were a=20
little bit more self contained in this respect.</FONT></FONT></P>
<P dir=3Dltr><FONT size=3D2><FONT=20
=
face=3DArial>--<BR>knut</FONT></P></FONT></BLOCKQUOTE ></BLOCKQUOTE></BODY=
></HTML>
------=_NextPart_000_000A_01C32F30.7D6E6B70--
|
|
|
| Re: getting started with JETEmitter [message #377837 is a reply to message #377825] |
Tue, 10 June 2003 12:10   |
|
Originally posted by: remko.popma.azzurri.jp
Knut,
I've actually started working on a JET tutorial, hoping I can post it as
an article for the Eclipse site... :-()
Remko
Knut Wannheden wrote:
>
> Thanks again for the tips! Seems like you know JET well enough that you
> could write a user's guide for it :-)
>
> --
> knut
>
|
|
|
| Re: getting started with JETEmitter [message #377851 is a reply to message #377837] |
Wed, 11 June 2003 06:23  |
Knut Wannheden Messages: 283 Registered: July 2009 |
Senior Member |
|
|
Remko,
Great news!
Regarding the skeleton directive tip you gave me: It looks like the skeleton
can be specified with any URI. So I should also be able to have the
skeleton in a Jar file and reference it using an URI like
"jar:file:/C|/foo.jar!/my.skeleton".
Cheers,
--
knut
"Remko Popma" <remko.popma@azzurri.jp> wrote in message
news:3EE602FC.9040406@azzurri.jp...
> Knut,
>
> I've actually started working on a JET tutorial, hoping I can post it as
> an article for the Eclipse site... :-()
>
> Remko
>
>
> Knut Wannheden wrote:
> >
> > Thanks again for the tips! Seems like you know JET well enough that you
> > could write a user's guide for it :-)
> >
> > --
> > knut
> >
>
|
|
|
Goto Forum:
Current Time: Sat May 25 19:32:57 EDT 2013
Powered by FUDForum. Page generated in 0.04069 seconds
|