Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse Platform » instantiate a class from the workspace of the running plugin
instantiate a class from the workspace of the running plugin [message #331619] Sun, 14 September 2008 17:33 Go to next message
Georgy is currently offline GeorgyFriend
Messages: 4
Registered: July 2009
Junior Member
I posted this in eclipse-dzone bu nobody could help me, so i post it here.

I'm trying to get an instance of a class from the package-explorer of a
running plugin.

I defined a PopupAction "CreateInstanceAction" in the context menue for
ICompilationUnits like this:


<objectContribution
[...]
objectClass="org.eclipse.jdt.core.ICompilationUnit">

So when I right-click on the .java-File in the Package-Explorer I get
the Option "instantiate". This option should instantiate the defined
class with the default empty constructor and print the object into the
plugins-console. Unfortunately I get the ClassNotFoundException.

This is how I do it:

1.First I take the class name from the ICompilationUnit, which
represents the selected item in the package explorer:


String className = anUnit.getTypes()[0].getFullyQualifiedName();

So className is something like "org.myapp.mypackage.MyClass"and this is
a class in the client's workspace.


2. Then I take the bundle from the Activator class and load it:



Class myClass =
Activator.getDefault().getBundle().loadClass(className);

3. The last step should be the instantiation of the class, that I created:


System.out.println(myClass.newInstance());


When I use the context menue action to print the instantiated object
eclipse throws a ClassNotFound-exception on the second line - the
loadClass(className)-Method.

What am I doing wrong? Does somebody has a solution for this?
Re: instantiate a class from the workspace of the running plugin [message #331621 is a reply to message #331619] Sun, 14 September 2008 20:08 Go to previous messageGo to next message
Will Horn is currently offline Will HornFriend
Messages: 265
Registered: July 2009
Senior Member
Just because Eclipse is compiling a class does not mean Eclipse can run
that compiled code internally. Unless I am missing something, you are
trying to add compiled code to the VM at runtime which I do not think is
an easy task.

Activator.getDefault().getBundle().loadClass() only has access to a
limited number of classes determined by the OSGi environment.

Maybe you can use some internal Eclipse functionality to launch a new
java process with your compiled class (that's what happens when you run
code in the IDE). The details of doing this are beyond me.

Georgy Dobrev wrote:
> I posted this in eclipse-dzone bu nobody could help me, so i post it here.
>
> I'm trying to get an instance of a class from the package-explorer of a
> running plugin.
>
> I defined a PopupAction "CreateInstanceAction" in the context menue for
> ICompilationUnits like this:
>
>
> <objectContribution
> [...]
> objectClass="org.eclipse.jdt.core.ICompilationUnit">
>
> So when I right-click on the .java-File in the Package-Explorer I get
> the Option "instantiate". This option should instantiate the defined
> class with the default empty constructor and print the object into the
> plugins-console. Unfortunately I get the ClassNotFoundException.
>
> This is how I do it:
>
> 1.First I take the class name from the ICompilationUnit, which
> represents the selected item in the package explorer:
>
>
> String className = anUnit.getTypes()[0].getFullyQualifiedName();
>
> So className is something like "org.myapp.mypackage.MyClass"and this is
> a class in the client's workspace.
>
>
> 2. Then I take the bundle from the Activator class and load it:
>
>
>
> Class myClass =
> Activator.getDefault().getBundle().loadClass(className);
>
> 3. The last step should be the instantiation of the class, that I created:
>
>
> System.out.println(myClass.newInstance());
>
>
> When I use the context menue action to print the instantiated object
> eclipse throws a ClassNotFound-exception on the second line - the
> loadClass(className)-Method.
>
> What am I doing wrong? Does somebody has a solution for this?
Re: instantiate a class from the workspace of the running plugin [message #331625 is a reply to message #331621] Sun, 14 September 2008 21:32 Go to previous messageGo to next message
Georgy is currently offline GeorgyFriend
Messages: 4
Registered: July 2009
Junior Member
Is there a way to create my own class loader that loads the class? Maybe
there is such plugin?


Will Horn schrieb:
> Just because Eclipse is compiling a class does not mean Eclipse can run
> that compiled code internally. Unless I am missing something, you are
> trying to add compiled code to the VM at runtime which I do not think is
> an easy task.
>
> Activator.getDefault().getBundle().loadClass() only has access to a
> limited number of classes determined by the OSGi environment.
>
> Maybe you can use some internal Eclipse functionality to launch a new
> java process with your compiled class (that's what happens when you run
> code in the IDE). The details of doing this are beyond me.
>
> Georgy Dobrev wrote:
>> I posted this in eclipse-dzone bu nobody could help me, so i post it
>> here.
>>
>> I'm trying to get an instance of a class from the package-explorer of
>> a running plugin.
>>
>> I defined a PopupAction "CreateInstanceAction" in the context menue
>> for ICompilationUnits like this:
>>
>>
>> <objectContribution
>> [...]
>> objectClass="org.eclipse.jdt.core.ICompilationUnit">
>>
>> So when I right-click on the .java-File in the Package-Explorer I get
>> the Option "instantiate". This option should instantiate the defined
>> class with the default empty constructor and print the object into the
>> plugins-console. Unfortunately I get the ClassNotFoundException.
>>
>> This is how I do it:
>>
>> 1.First I take the class name from the ICompilationUnit, which
>> represents the selected item in the package explorer:
>>
>>
>> String className = anUnit.getTypes()[0].getFullyQualifiedName();
>>
>> So className is something like "org.myapp.mypackage.MyClass"and this
>> is a class in the client's workspace.
>>
>>
>> 2. Then I take the bundle from the Activator class and load it:
>>
>>
>>
>> Class myClass =
>> Activator.getDefault().getBundle().loadClass(className);
>>
>> 3. The last step should be the instantiation of the class, that I
>> created:
>>
>>
>> System.out.println(myClass.newInstance());
>>
>>
>> When I use the context menue action to print the instantiated object
>> eclipse throws a ClassNotFound-exception on the second line - the
>> loadClass(className)-Method.
>>
>> What am I doing wrong? Does somebody has a solution for this?
Re: instantiate a class from the workspace of the running plugin [message #331627 is a reply to message #331621] Sun, 14 September 2008 22:39 Go to previous messageGo to next message
Georgy is currently offline GeorgyFriend
Messages: 4
Registered: July 2009
Junior Member
Will Horn schrieb:
> Just because Eclipse is compiling a class does not mean Eclipse can run
> that compiled code internally. Unless I am missing something, you are
> trying to add compiled code to the VM at runtime which I do not think is
> an easy task.

Actually I don't want to compile the code, because the user of my plugin
is supposed to compile it in java (in the common case eclipse builds the
classes automatically). I only want to create an object of the already
exsisting and compiled class, that was created by the user.


>
> Activator.getDefault().getBundle().loadClass() only has access to a
> limited number of classes determined by the OSGi environment

So, is there somewhere a loadClass()-Method that loads the user classes,
that are not known at compile-time?

Thanks in advance!


> Georgy Dobrev wrote:
>> I posted this in eclipse-dzone bu nobody could help me, so i post it
>> here.
>>
>> I'm trying to get an instance of a class from the package-explorer of
>> a running plugin.
>>
>> I defined a PopupAction "CreateInstanceAction" in the context menue
>> for ICompilationUnits like this:
>>
>>
>> <objectContribution
>> [...]
>> objectClass="org.eclipse.jdt.core.ICompilationUnit">
>>
>> So when I right-click on the .java-File in the Package-Explorer I get
>> the Option "instantiate". This option should instantiate the defined
>> class with the default empty constructor and print the object into the
>> plugins-console. Unfortunately I get the ClassNotFoundException.
>>
>> This is how I do it:
>>
>> 1.First I take the class name from the ICompilationUnit, which
>> represents the selected item in the package explorer:
>>
>>
>> String className = anUnit.getTypes()[0].getFullyQualifiedName();
>>
>> So className is something like "org.myapp.mypackage.MyClass"and this
>> is a class in the client's workspace.
>>
>>
>> 2. Then I take the bundle from the Activator class and load it:
>>
>>
>>
>> Class myClass =
>> Activator.getDefault().getBundle().loadClass(className);
>>
>> 3. The last step should be the instantiation of the class, that I
>> created:
>>
>>
>> System.out.println(myClass.newInstance());
>>
>>
>> When I use the context menue action to print the instantiated object
>> eclipse throws a ClassNotFound-exception on the second line - the
>> loadClass(className)-Method.
>>
>> What am I doing wrong? Does somebody has a solution for this?
Re: instantiate a class from the workspace of the running plugin [message #331629 is a reply to message #331627] Sun, 14 September 2008 22:57 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33198
Registered: July 2009
Senior Member
Georgy,

Many people will likely advise you that it's a bad idea to load a user
class into the IDE itself. It's a fact. After all, it can corrupt the
IDE. You might want to look at the source code for EMF's
org.eclipse.emf.codegen.jet.JETEmitter to see how it uses a
URLClassLoader to load compiled classes from an Eclipse project. The
idea here being that JET templates are compiled to Java, those are
compiled to a .class file, and if we want to dynamically execute a JET
template, we need to load that .class and execute it...


Georgy Dobrev wrote:
> Will Horn schrieb:
>> Just because Eclipse is compiling a class does not mean Eclipse can
>> run that compiled code internally. Unless I am missing something,
>> you are trying to add compiled code to the VM at runtime which I do
>> not think is an easy task.
>
> Actually I don't want to compile the code, because the user of my
> plugin is supposed to compile it in java (in the common case eclipse
> builds the classes automatically). I only want to create an object of
> the already exsisting and compiled class, that was created by the user.
>
>
>>
>> Activator.getDefault().getBundle().loadClass() only has access to a
>> limited number of classes determined by the OSGi environment
>
> So, is there somewhere a loadClass()-Method that loads the user
> classes, that are not known at compile-time?
>
> Thanks in advance!
>
>
>> Georgy Dobrev wrote:
>>> I posted this in eclipse-dzone bu nobody could help me, so i post it
>>> here.
>>>
>>> I'm trying to get an instance of a class from the package-explorer
>>> of a running plugin.
>>>
>>> I defined a PopupAction "CreateInstanceAction" in the context menue
>>> for ICompilationUnits like this:
>>>
>>>
>>> <objectContribution
>>> [...]
>>> objectClass="org.eclipse.jdt.core.ICompilationUnit">
>>>
>>> So when I right-click on the .java-File in the Package-Explorer I
>>> get the Option "instantiate". This option should instantiate the
>>> defined class with the default empty constructor and print the
>>> object into the plugins-console. Unfortunately I get the
>>> ClassNotFoundException.
>>>
>>> This is how I do it:
>>>
>>> 1.First I take the class name from the ICompilationUnit, which
>>> represents the selected item in the package explorer:
>>>
>>>
>>> String className = anUnit.getTypes()[0].getFullyQualifiedName();
>>>
>>> So className is something like "org.myapp.mypackage.MyClass"and this
>>> is a class in the client's workspace.
>>>
>>>
>>> 2. Then I take the bundle from the Activator class and load it:
>>>
>>>
>>>
>>> Class myClass =
>>> Activator.getDefault().getBundle().loadClass(className);
>>>
>>> 3. The last step should be the instantiation of the class, that I
>>> created:
>>>
>>>
>>> System.out.println(myClass.newInstance());
>>>
>>>
>>> When I use the context menue action to print the instantiated object
>>> eclipse throws a ClassNotFound-exception on the second line - the
>>> loadClass(className)-Method.
>>>
>>> What am I doing wrong? Does somebody has a solution for this?


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: instantiate a class from the workspace of the running plugin [message #331673 is a reply to message #331629] Tue, 16 September 2008 08:43 Go to previous messageGo to next message
Georgy is currently offline GeorgyFriend
Messages: 4
Registered: July 2009
Junior Member
Ed Merks schrieb:
> Many people will likely advise you that it's a bad idea to load a user
> class into the IDE itself. It's a fact. After all, it can corrupt the
> IDE. You might want to look at the source code for EMF's
> org.eclipse.emf.codegen.jet.JETEmitter to see how it uses a
> URLClassLoader to load compiled classes from an Eclipse project. The
> idea here being that JET templates are compiled to Java, those are
> compiled to a .class file, and if we want to dynamically execute a JET
> template, we need to load that .class and execute it...
>


I think that this is be the power of eclipse - helping us develop applications that help developers. So the feature for loading user-defined classes should be build in.

Thanks for your advice to use the URLClassLoader. I finally found a solution for the problem. Since i couldn'n find the source code of the JETErmitter, I'm not sure if this is the right way to do this, but it (still) works for me.

I implemented my own ClassLoader that has an inner URLClassLoader like this:


public class ClientProjectClassLoader {

private URLClassLoader innerCL;

/** an automatic generated delegate method */
public Class<?> loadClass(String name) throws ClassNotFoundException {
return innerCL.loadClass(name);
}

public ClientProjectClassLoader(ICompilationUnit c, ClassLoader parent) {
String unitPath = c.getResource().getProject().getLocationURI()
.toString();
URL binURI = null;
try {
binURI = new URL(unitPath + "/bin/");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
innerCL = new URLClassLoader(new URL[] { binURI }, parent);
}

}

The constructor just takes the ICompilationUnit that is selected by the User and the class loader of the plugin

Activator.getDefault().getDescriptor().getPluginClassLoader( )


So when I need the class-object, coresponding to the ICompilationUnit I just call the loadClass()-method from the instance of my classLoader. This code should be written in ther run()-Method of the PopUp-Action. anUnit is the selected ICompilationUnit.

ClientProjectClassLoader cpcl = new ClientProjectClassLoader(anUnit, Activator.getDefault().getDescriptor().getPluginClassLoader( ));
Class myClass = cpcl.loadClass(className);

I'm not sure, why I need to give the plugin class loader as parameter. Without this I get an exception. Maybe it's because the client classes use some classes form libraries only known in the plugin.

Is there a way to get the bin-Path of the project instead of manually appending the string "/bin/" to the absolute path of the project?


Bye


>
> Georgy Dobrev wrote:
>> Will Horn schrieb:
>>> Just because Eclipse is compiling a class does not mean Eclipse can
>>> run that compiled code internally. Unless I am missing something,
>>> you are trying to add compiled code to the VM at runtime which I do
>>> not think is an easy task.
>>
>> Actually I don't want to compile the code, because the user of my
>> plugin is supposed to compile it in java (in the common case eclipse
>> builds the classes automatically). I only want to create an object of
>> the already exsisting and compiled class, that was created by the user.
>>
>>
>>>
>>> Activator.getDefault().getBundle().loadClass() only has access to a
>>> limited number of classes determined by the OSGi environment
>>
>> So, is there somewhere a loadClass()-Method that loads the user
>> classes, that are not known at compile-time?
>>
>> Thanks in advance!
>>
>>
>>> Georgy Dobrev wrote:
>>>> I posted this in eclipse-dzone bu nobody could help me, so i post it
>>>> here.
>>>>
>>>> I'm trying to get an instance of a class from the package-explorer
>>>> of a running plugin.
>>>>
>>>> I defined a PopupAction "CreateInstanceAction" in the context menue
>>>> for ICompilationUnits like this:
>>>>
>>>>
>>>> <objectContribution
>>>> [...]
>>>> objectClass="org.eclipse.jdt.core.ICompilationUnit">
>>>>
>>>> So when I right-click on the .java-File in the Package-Explorer I
>>>> get the Option "instantiate". This option should instantiate the
>>>> defined class with the default empty constructor and print the
>>>> object into the plugins-console. Unfortunately I get the
>>>> ClassNotFoundException.
>>>>
>>>> This is how I do it:
>>>>
>>>> 1.First I take the class name from the ICompilationUnit, which
>>>> represents the selected item in the package explorer:
>>>>
>>>>
>>>> String className = anUnit.getTypes()[0].getFullyQualifiedName();
>>>>
>>>> So className is something like "org.myapp.mypackage.MyClass"and this
>>>> is a class in the client's workspace.
>>>>
>>>>
>>>> 2. Then I take the bundle from the Activator class and load it:
>>>>
>>>>
>>>>
>>>> Class myClass =
>>>> Activator.getDefault().getBundle().loadClass(className);
>>>>
>>>> 3. The last step should be the instantiation of the class, that I
>>>> created:
>>>>
>>>>
>>>> System.out.println(myClass.newInstance());
>>>>
>>>>
>>>> When I use the context menue action to print the instantiated object
>>>> eclipse throws a ClassNotFound-exception on the second line - the
>>>> loadClass(className)-Method.
>>>>
>>>> What am I doing wrong? Does somebody has a solution for this?
Re: instantiate a class from the workspace of the running plugin [message #331680 is a reply to message #331673] Tue, 16 September 2008 10:48 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33198
Registered: July 2009
Senior Member
Georgy,

Comments below.

Georgy Dobrev wrote:
> Ed Merks schrieb:
>> Many people will likely advise you that it's a bad idea to load a
>> user class into the IDE itself. It's a fact. After all, it can
>> corrupt the IDE. You might want to look at the source code for
>> EMF's org.eclipse.emf.codegen.jet.JETEmitter to see how it uses a
>> URLClassLoader to load compiled classes from an Eclipse project. The
>> idea here being that JET templates are compiled to Java, those are
>> compiled to a .class file, and if we want to dynamically execute a
>> JET template, we need to load that .class and execute it...
>>
>
>
> I think that this is be the power of eclipse - helping us develop
> applications that help developers. So the feature for loading
> user-defined classes should be build in.
I'm not sure that your conclusion follows your first statement. Eclipse
supports launching a new instance of Eclipse in which the user classes
are loaded, but you'll find that trying to argue that user classes
should be loaded directly into the running IDE itself will yield counter
arguments about the possibility or even likelihood of errors in the
user's code corrupting the IDE process...
> Thanks for your advice to use the URLClassLoader. I finally found a
> solution for the problem. Since i couldn'n find the source code of the
> JETErmitter,
http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf/plugins/org.eclipse.emf.codegen/src/org/eclipse /emf/codegen/jet/JETEmitter.java?root=Modeling_Project&v iew=markup
< http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf/plugins/org.eclipse.emf.codegen/src/org/eclipse /emf/codegen/jet/JETEmitter.java?root=Modeling_Project&v iew=markup>
> I'm not sure if this is the right way to do this, but it (still) works
> for me.
> I implemented my own ClassLoader that has an inner URLClassLoader like
> this:
>
>
> public class ClientProjectClassLoader {
>
> private URLClassLoader innerCL;
>
> /** an automatic generated delegate method */
> public Class<?> loadClass(String name) throws
> ClassNotFoundException {
> return innerCL.loadClass(name);
> }
>
> public ClientProjectClassLoader(ICompilationUnit c, ClassLoader
> parent) {
> String unitPath = c.getResource().getProject().getLocationURI()
> .toString();
> URL binURI = null;
> try {
> binURI = new URL(unitPath + "/bin/");
> } catch (MalformedURLException e) {
> // TODO Auto-generated catch block
> e.printStackTrace();
> }
> innerCL = new URLClassLoader(new URL[] { binURI }, parent);
> }
>
> }
You should really check what the output folder is and in general you
need to consider that the project might have things on the classpath
that aren't visible in your running IDE...
>
> The constructor just takes the ICompilationUnit that is selected by
> the User and the class loader of the plugin
> Activator.getDefault().getDescriptor().getPluginClassLoader( )
>
>
> So when I need the class-object, coresponding to the ICompilationUnit
> I just call the loadClass()-method from the instance of my
> classLoader. This code should be written in ther run()-Method of the
> PopUp-Action. anUnit is the selected ICompilationUnit.
> ClientProjectClassLoader cpcl = new
> ClientProjectClassLoader(anUnit,
> Activator.getDefault().getDescriptor().getPluginClassLoader( ));
> Class myClass = cpcl.loadClass(className);
>
> I'm not sure, why I need to give the plugin class loader as parameter.
> Without this I get an exception. Maybe it's because the client classes
> use some classes form libraries only known in the plugin.
> Is there a way to get the bin-Path of the project instead of manually
> appending the string "/bin/" to the absolute path of the project?
Yes. Have a look at the source for which I provided the link.
>
>
> Bye
>
>
>>
>> Georgy Dobrev wrote:
>>> Will Horn schrieb:
>>>> Just because Eclipse is compiling a class does not mean Eclipse can
>>>> run that compiled code internally. Unless I am missing something,
>>>> you are trying to add compiled code to the VM at runtime which I do
>>>> not think is an easy task.
>>>
>>> Actually I don't want to compile the code, because the user of my
>>> plugin is supposed to compile it in java (in the common case eclipse
>>> builds the classes automatically). I only want to create an object
>>> of the already exsisting and compiled class, that was created by the
>>> user.
>>>
>>>
>>>>
>>>> Activator.getDefault().getBundle().loadClass() only has access to a
>>>> limited number of classes determined by the OSGi environment
>>>
>>> So, is there somewhere a loadClass()-Method that loads the user
>>> classes, that are not known at compile-time?
>>>
>>> Thanks in advance!
>>>
>>>
>>>> Georgy Dobrev wrote:
>>>>> I posted this in eclipse-dzone bu nobody could help me, so i post
>>>>> it here.
>>>>>
>>>>> I'm trying to get an instance of a class from the package-explorer
>>>>> of a running plugin.
>>>>>
>>>>> I defined a PopupAction "CreateInstanceAction" in the context
>>>>> menue for ICompilationUnits like this:
>>>>>
>>>>>
>>>>> <objectContribution
>>>>> [...]
>>>>> objectClass="org.eclipse.jdt.core.ICompilationUnit">
>>>>>
>>>>> So when I right-click on the .java-File in the Package-Explorer I
>>>>> get the Option "instantiate". This option should instantiate the
>>>>> defined class with the default empty constructor and print the
>>>>> object into the plugins-console. Unfortunately I get the
>>>>> ClassNotFoundException.
>>>>>
>>>>> This is how I do it:
>>>>>
>>>>> 1.First I take the class name from the ICompilationUnit, which
>>>>> represents the selected item in the package explorer:
>>>>>
>>>>>
>>>>> String className =
>>>>> anUnit.getTypes()[0].getFullyQualifiedName();
>>>>>
>>>>> So className is something like "org.myapp.mypackage.MyClass"and
>>>>> this is a class in the client's workspace.
>>>>>
>>>>>
>>>>> 2. Then I take the bundle from the Activator class and load it:
>>>>>
>>>>>
>>>>>
>>>>> Class myClass =
>>>>> Activator.getDefault().getBundle().loadClass(className);
>>>>>
>>>>> 3. The last step should be the instantiation of the class, that I
>>>>> created:
>>>>>
>>>>>
>>>>> System.out.println(myClass.newInstance());
>>>>>
>>>>>
>>>>> When I use the context menue action to print the instantiated
>>>>> object eclipse throws a ClassNotFound-exception on the second line
>>>>> - the loadClass(className)-Method.
>>>>>
>>>>> What am I doing wrong? Does somebody has a solution for this?


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: instantiate a class from the workspace of the running plugin [message #331682 is a reply to message #331619] Tue, 16 September 2008 11:37 Go to previous messageGo to next message
Paul Webster is currently offline Paul WebsterFriend
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

Are you potentially dealing with java projects or only with plugin projects?

One of the practices we investigated while looking at scripting was
hosting a workspace plugin *in* your running eclipse (so that Java
scriptlets could be edited and then immediately executed). But this
only helps with plugins, not with plain java projects (where, as Ed
mentioned, you would most assuredly have to fool around with a
URLClassLoader of some type).

PW


--
Paul Webster
http://wiki.eclipse.org/Platform_Command_Framework
http://wiki.eclipse.org/Command_Core_Expressions
http://wiki.eclipse.org/Menu_Contributions
http://wiki.eclipse.org/Menus_Extension_Mapping
http://help.eclipse.org/ganymede/index.jsp?topic=/org.eclips e.platform.doc.isv/guide/workbench.htm


Re: instantiate a class from the workspace of the running plugin [message #331690 is a reply to message #331673] Tue, 16 September 2008 14:51 Go to previous message
Eclipse UserFriend
Originally posted by: wegener.cboenospam.com

"Georgy Dobrev" <goga@cs.tu-berlin.de> wrote in message
news:ganrjl$m7g$1@build.eclipse.org...
> Ed Merks schrieb:
> > Many people will likely advise you that it's a bad idea to load a user
> > class into the IDE itself. It's a fact. After all, it can corrupt the
> > IDE. You might want to look at the source code for EMF's
> > org.eclipse.emf.codegen.jet.JETEmitter to see how it uses a
> > URLClassLoader to load compiled classes from an Eclipse project. The
> > idea here being that JET templates are compiled to Java, those are
> > compiled to a .class file, and if we want to dynamically execute a JET
> > template, we need to load that .class and execute it...
> >
>
>
> I think that this is be the power of eclipse - helping us develop
applications that help developers. So the feature for loading user-defined
classes should be build in.

You need to spend some time thinking about what a class loader actually
does. First, it is going to try and resolve any class referenced by the
class being loaded. This means that your custom class loader will need to
be aware of the full runtime classpath necessary to load the class and all
of its depencencies.

Second, the classloader will run any static initializers defined in any of
the loaded classes. You will have no control over what is in this code and
it could effect the stability of the IDE by throwing exceptions, spawing
threads, etc.

Third, once loaded, you won't be able to easily pick up any changes made by
the user. The classloader will cache the class instance that is loaded. If
any instances of the class are created, they will need to be destroyed
before you can garbage collect the class and reload a new copy of it.

>
> Thanks for your advice to use the URLClassLoader. I finally found a
solution for the problem. Since i couldn'n find the source code of the
JETErmitter, I'm not sure if this is the right way to do this, but it
(still) works for me.
>
> I implemented my own ClassLoader that has an inner URLClassLoader like
this:
>
>
> public class ClientProjectClassLoader {
>
> private URLClassLoader innerCL;
>
> /** an automatic generated delegate method */
> public Class<?> loadClass(String name) throws ClassNotFoundException {
> return innerCL.loadClass(name);
> }
>
> public ClientProjectClassLoader(ICompilationUnit c, ClassLoader parent) {
> String unitPath = c.getResource().getProject().getLocationURI()
> .toString();
> URL binURI = null;
> try {
> binURI = new URL(unitPath + "/bin/");
> } catch (MalformedURLException e) {
> // TODO Auto-generated catch block
> e.printStackTrace();
> }
> innerCL = new URLClassLoader(new URL[] { binURI }, parent);
> }
>
> }
>
> The constructor just takes the ICompilationUnit that is selected by the
User and the class loader of the plugin
>
> Activator.getDefault().getDescriptor().getPluginClassLoader( )
>
>
> So when I need the class-object, coresponding to the ICompilationUnit I
just call the loadClass()-method from the instance of my classLoader. This
code should be written in ther run()-Method of the PopUp-Action. anUnit is
the selected ICompilationUnit.
>
> ClientProjectClassLoader cpcl = new ClientProjectClassLoader(anUnit,
Activator.getDefault().getDescriptor().getPluginClassLoader( ));
> Class myClass = cpcl.loadClass(className);
>
> I'm not sure, why I need to give the plugin class loader as parameter.
Without this I get an exception. Maybe it's because the client classes use
some classes form libraries only known in the plugin.
>
> Is there a way to get the bin-Path of the project instead of manually
appending the string "/bin/" to the absolute path of the project?
>
>
> Bye
>
>
> >
> > Georgy Dobrev wrote:
> >> Will Horn schrieb:
> >>> Just because Eclipse is compiling a class does not mean Eclipse can
> >>> run that compiled code internally. Unless I am missing something,
> >>> you are trying to add compiled code to the VM at runtime which I do
> >>> not think is an easy task.
> >>
> >> Actually I don't want to compile the code, because the user of my
> >> plugin is supposed to compile it in java (in the common case eclipse
> >> builds the classes automatically). I only want to create an object of
> >> the already exsisting and compiled class, that was created by the user.
> >>
> >>
> >>>
> >>> Activator.getDefault().getBundle().loadClass() only has access to a
> >>> limited number of classes determined by the OSGi environment
> >>
> >> So, is there somewhere a loadClass()-Method that loads the user
> >> classes, that are not known at compile-time?
> >>
> >> Thanks in advance!
> >>
> >>
> >>> Georgy Dobrev wrote:
> >>>> I posted this in eclipse-dzone bu nobody could help me, so i post it
> >>>> here.
> >>>>
> >>>> I'm trying to get an instance of a class from the package-explorer
> >>>> of a running plugin.
> >>>>
> >>>> I defined a PopupAction "CreateInstanceAction" in the context menue
> >>>> for ICompilationUnits like this:
> >>>>
> >>>>
> >>>> <objectContribution
> >>>> [...]
> >>>> objectClass="org.eclipse.jdt.core.ICompilationUnit">
> >>>>
> >>>> So when I right-click on the .java-File in the Package-Explorer I
> >>>> get the Option "instantiate". This option should instantiate the
> >>>> defined class with the default empty constructor and print the
> >>>> object into the plugins-console. Unfortunately I get the
> >>>> ClassNotFoundException.
> >>>>
> >>>> This is how I do it:
> >>>>
> >>>> 1.First I take the class name from the ICompilationUnit, which
> >>>> represents the selected item in the package explorer:
> >>>>
> >>>>
> >>>> String className =
anUnit.getTypes()[0].getFullyQualifiedName();
> >>>>
> >>>> So className is something like "org.myapp.mypackage.MyClass"and this
> >>>> is a class in the client's workspace.
> >>>>
> >>>>
> >>>> 2. Then I take the bundle from the Activator class and load it:
> >>>>
> >>>>
> >>>>
> >>>> Class myClass =
> >>>> Activator.getDefault().getBundle().loadClass(className);
> >>>>
> >>>> 3. The last step should be the instantiation of the class, that I
> >>>> created:
> >>>>
> >>>>
> >>>> System.out.println(myClass.newInstance());
> >>>>
> >>>>
> >>>> When I use the context menue action to print the instantiated object
> >>>> eclipse throws a ClassNotFound-exception on the second line - the
> >>>> loadClass(className)-Method.
> >>>>
> >>>> What am I doing wrong? Does somebody has a solution for this?
Previous Topic:Contribute to Resource Navigator New Submenu
Next Topic:Why org.eclipse.ui.file.newQuickMenu always is disabled? How can I use org.eclipse.ui.newWizards?
Goto Forum:
  


Current Time: Mon Aug 19 17:19:19 GMT 2024

Powered by FUDForum. Page generated in 0.03927 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top