I recently started using ImageJ and Java (I am an experienced C++ programmer). I am working on WinXP, SP3, ImageJ 1.42q, and Java 1.6.0_16. I wrote my first plugin, and that went smoothly. When I wrote the second plugin, I needed methods from the first plugin, so I imported it. When I try to compile it, I get the error message "Package XYZ_ does not exist", pointing to the import line. I am guessing the problem is that the compiler cannot find the XYZ_.class file. I have added the path to the folder containing the file to the system variable PATH, but this did not resolve the problem. Does anybody know how to get the compiler to link this file?
Thanks to anyone who can help. |
Put either the sources together in one path or give a package
declaration to your first plugin (the equivalent to a namespace in C++). For non-trivial plugins this is anyway the better idea. You can then import that plugin by import mynamespace.FirstPlugin; similar to using mynamespace::FirstPlugin; to announce mynamespace.FirstPlugin to ImageJ, you need a hack called plugins.config in the jar file that contains it or in the plugins folder alternatively to define what to call under which menu point. Explanation here: http://rsbweb.nih.gov/ij/plugins/jar-demo.html Best, Stephan On Sun, 2010-01-17 at 16:28 -0600, Bob wrote: > I recently started using ImageJ and Java (I am an experienced C++ programmer). I am working on WinXP, SP3, ImageJ 1.42q, and Java 1.6.0_16. I wrote my first plugin, and that went smoothly. When I wrote the second plugin, I needed methods from the first plugin, so I imported it. When I try to compile it, I get the error message "Package XYZ_ does not exist", pointing to the import line. I am guessing the problem is that the compiler cannot find the XYZ_.class file. I have added the path to the folder containing the file to the system variable PATH, but this did not resolve the problem. Does anybody know how to get the compiler to link this file? > > Thanks to anyone who can help. |
In reply to this post by Bob Loushin
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1 Hello, for ImageJ the plugin (i.e. the class that implements the PlugIn interface) must not be in any package. Therefore it can not be imported from anywhere else. IMHO the best thing to do is to put the code into another class that can be in a package and to import this package into the two plugins. Volker Bob wrote: > I recently started using ImageJ and Java (I am an experienced C++ programmer). I am working on WinXP, SP3, ImageJ 1.42q, and Java 1.6.0_16. I wrote my first plugin, and that went smoothly. When I wrote the second plugin, I needed methods from the first plugin, so I imported it. When I try to compile it, I get the error message "Package XYZ_ does not exist", pointing to the import line. I am guessing the problem is that the compiler cannot find the XYZ_.class file. I have added the path to the folder containing the file to the system variable PATH, but this did not resolve the problem. Does anybody know how to get the compiler to link this file? > > Thanks to anyone who can help. > -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAktUJisACgkQ0gXPLVKexCcbkQCfc8hWquZiG8UYATtBzM6X8y5B NpIAmgOdR8QaB/8HRk5V1YOsUiYFSPpb =3WDY -----END PGP SIGNATURE----- -- passerelle antivirus du campus CNRS de Montpellier -- |
Hi Bob,
I've had similar problems in the past but now: 1) Implement PlugIn within packages 2) Call methods from other PlugIn classes in other sub-packages 3) Call methods and use classes from imported .jars This is really very convenient and means I can reuse code between my plugins, as well as have some non-PlugIn utility classes (but my code is, shall we say, a bit "agricultural") (Though I now better understand Volker's preference to have the PlugIns in the root directory, calling classes in the packages - the PlugIn classes talk to ImageJ's API and the other classes, which "do the work". http://n2.nabble.com/plugins-config-Plugin-or-class-not-found-exception-tp2245232p2245464.html). The special sauce is in plugins.config (which is sensitive to whitespace incidentally, you must use space and not tab). A PlugIn in the root directory of my jar is referred to in plugins.config like this: Plugins>BoneJ, "Fit Sphere", Fit_Sphere It gets the menu item Plugins->BoneJ->Fit Sphere A plugin in a package directory is referred to like this: Plugins>BoneJ, "Moments 3D", org.doube.bonej.Moments It gets the menu item Plugins->BoneJ->Moments 3D I think Stephan covered the rest; importing classes for use in your new PlugIn goes like: import org.doube.util.ResultInserter; I hope these tips help, Michael On 18/01/2010 09:13, Volker Baecker wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > Hello, > for ImageJ the plugin (i.e. the class that implements the PlugIn > interface) must not be in any package. Therefore it can not be imported > from anywhere else. > IMHO the best thing to do is to put the code into another class that can > be in a package and to import this package into the two plugins. > Volker > > Bob wrote: >> I recently started using ImageJ and Java (I am an experienced C++ programmer). I am working on WinXP, SP3, ImageJ 1.42q, and Java 1.6.0_16. I wrote my first plugin, and that went smoothly. When I wrote the second plugin, I needed methods from the first plugin, so I imported it. When I try to compile it, I get the error message "Package XYZ_ does not exist", pointing to the import line. I am guessing the problem is that the compiler cannot find the XYZ_.class file. I have added the path to the folder containing the file to the system variable PATH, but this did not resolve the problem. Does anybody know how to get the compiler to link this file? >> >> Thanks to anyone who can help. >> > -----BEGIN PGP SIGNATURE----- > Version: GnuPG v1.4.9 (GNU/Linux) > Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org > > iEYEARECAAYFAktUJisACgkQ0gXPLVKexCcbkQCfc8hWquZiG8UYATtBzM6X8y5B > NpIAmgOdR8QaB/8HRk5V1YOsUiYFSPpb > =3WDY > -----END PGP SIGNATURE----- > |
In reply to this post by Bob Loushin
Bob wrote:
> I recently started using ImageJ and Java (I am an experienced C++ programmer). I am working on WinXP, SP3, ImageJ 1.42q, and Java 1.6.0_16. I wrote my first plugin, and that went smoothly. When I wrote the second plugin, I needed methods from the first plugin, so I imported it. When I try to compile it, I get the error message "Package XYZ_ does not exist", pointing to the import line. I am guessing the problem is that the compiler cannot find the XYZ_.class file. I have added the path to the folder containing the file to the system variable PATH, but this did not resolve the problem. Does anybody know how to get the compiler to link this file? > > Thanks to anyone who can help. > > Classes are searched for on the CLASSPATH (rather than PATH). You could make a system variable called path but it is better to define the classpath in your IDE. |
In reply to this post by Bob Loushin
I'd like to thank everyone who responded. Mr. Saalfeld seems to have pointed me down the right path, but I haven't had success following it. In particular, the following works:
Experiment 1: test_1.java: //package my_stuff; import ij.*; import ij.process.*; import ij.gui.*; import java.awt.*; import ij.plugin.*; public class test_1 implements PlugIn { public void run(String arg) { shared_method(); } public void shared_method() { IJ.showMessage("test_1","Hello world!"); } } plugins.config: # Name: Test_Plugin # Author: Bob # Version: 1.0 # Date: 1/18/10 # Requires: ImageJ 1.31s Plugins>Test, "Test 1", test_1("run") I compile a .class out of the java file using ImageJ>Plugins>Compile and Run..., wrap the whole thing in a .jar using the command jar cvfM Test.jar test_1.class test_1.java plugins.config I put this in the plugins folder, fired up ImageJ, and Test 1 was there and ran as expected. Experiment 2: Then I uncommented the first line of the .java file and changed the last line of the plugins.config to read Plugins>Test, "Test 1", my_stuff.test_1("run") I compile the .class, but of course when I do the Compile and Run..., the run part fails, because now my class is inside a package. But it still compiled, and the .class should be good, so I proceed. I use the same jar command as before, restart ImageJ, and try to run it. Unfortunately, it again fails. Apparently, there is still a detail I do not understand. Experiment 3: The ultimate goal is to be able to write a test_2.java which will look like the following: test_2.java: //package my_stuff; import test_1.*; //This line may not be necessary, or it might need to be import test_1; my Java knowledge is weak on this point, but I'll experiment. import ij.*; import ij.process.*; import ij.gui.*; import java.awt.*; import ij.plugin.*; public class test_2 implements PlugIn { public void run(String arg) { test_1 temp; temp.shared_method(); } } I can't try this until I can get Experiment 2 to work. Can anyone tell me where I've gone wrong? Thanks! Bob |
Your problems are on Java syntax, not ImageJ ;)---read:
http://java.sun.com/docs/books/tutorial/java/index.html I your case, what you're trying is to use an instance method in a static way. In Java, an object is not instantiated just by declaring it, you have to use new. So either: test_1.java: public class test_1 implements PlugIn { public void run(String arg) { shared_method(); } static public void shared_method() { IJ.showMessage("test_1","Hello world!"); } } or leaving test_1 as you had it before: test_2.java: public class test_2 implements PlugIn { public void run(String arg) { test_1 temp = new test_1(); temp.shared_method(); } } The previous test_1/test_2 combination shouldn't have been compilable. Best, Stephan |
Stephan,
You're right, of course, I should have used a new in my test_2.java example (it is in the original code, but didn't survive when I rewrote the simplified illustration). But where I'm stuck is at the point before test_2 enters the picture. Basically, I can't get experiment 2 (which only involves the packaged version of test_1) to work. You're also correct that this may be a Java problem, not an ImageJ problem, since I'm new to both. To focus a bit more clearly on my current stopper, this fails: test_1.java: package my_stuff; import ij.*; import ij.process.*; import ij.gui.*; import java.awt.*; import ij.plugin.*; public class test_1 implements PlugIn { public void run(String arg) { shared_method(); } public void shared_method() { IJ.showMessage("test_1","Hello world!"); } } plugins.config: # Name: Test_Plugin # Author: Bob # Version: 1.0 # Date: 1/18/10 # Requires: ImageJ 1.31s Plugins>Test, "Test 1", my_stuff.test_1("run") The issue may be in the way I compile, by just using the "Compile and Run..." in ImageJ to generate test_1.class, and then manually making the .jar file using "jar cvfM Test.jar test_1.class test_1.java plugins.config". However, it seems more likely to me that I have the syntax wrong in the last line of plugins.config. The error message I am getting is: "Plugin or class not found: 'my_stuff.test_1' (java.lang.ClassNotFoundException: my_stuff.test_1)" > Your problems are on Java syntax, not ImageJ ;)---read: > > http://java.sun.com/docs/books/tutorial/java/index.html > > I your case, what you're trying is to use an instance method in a static > way. In Java, an object is not instantiated just by declaring it, you > have to use new. So either: > > test_1.java: > > public class test_1 implements PlugIn { > > public void run(String arg) { shared_method(); } > > static public void shared_method() { IJ.showMessage("test_1","Hello > world!"); } > } > > or leaving test_1 as you had it before: > > test_2.java: > > public class test_2 implements PlugIn { > > public void run(String arg) { > test_1 temp = new test_1(); > temp.shared_method(); > } > > } > > The previous test_1/test_2 combination shouldn't have been compilable. > > Best, > Stephan |
Bob,
You don't have to put ("run") at the end of your plugins.config lines. Plugins>Test, "Test 1", my_stuff.test_1 should work. Michael Bob wrote: > Stephan, > > You're right, of course, I should have used a new in my test_2.java example > (it is in the original code, but didn't survive when I rewrote the > simplified illustration). But where I'm stuck is at the point before test_2 > enters the picture. Basically, I can't get experiment 2 (which only > involves the packaged version of test_1) to work. You're also correct that > this may be a Java problem, not an ImageJ problem, since I'm new to both. > To focus a bit more clearly on my current stopper, this fails: > > test_1.java: > package my_stuff; > > import ij.*; > import ij.process.*; > import ij.gui.*; > import java.awt.*; > import ij.plugin.*; > > public class test_1 implements PlugIn { > > public void run(String arg) { shared_method(); } > > public void shared_method() { IJ.showMessage("test_1","Hello world!"); } > } > > > plugins.config: > > # Name: Test_Plugin > > # Author: Bob > # Version: 1.0 > # Date: 1/18/10 > # Requires: ImageJ 1.31s > > Plugins>Test, "Test 1", my_stuff.test_1("run") > > The issue may be in the way I compile, by just using the "Compile and > Run..." in ImageJ to generate test_1.class, and then manually making the > .jar file using "jar cvfM Test.jar test_1.class test_1.java plugins.config". > However, it seems more likely to me that I have the syntax wrong in the last > line of plugins.config. The error message I am getting is: "Plugin or > class not found: 'my_stuff.test_1' (java.lang.ClassNotFoundException: > my_stuff.test_1)" > > >> Your problems are on Java syntax, not ImageJ ;)---read: >> >> http://java.sun.com/docs/books/tutorial/java/index.html >> >> I your case, what you're trying is to use an instance method in a static >> way. In Java, an object is not instantiated just by declaring it, you >> have to use new. So either: >> >> test_1.java: >> >> public class test_1 implements PlugIn { >> >> public void run(String arg) { shared_method(); } >> >> static public void shared_method() { IJ.showMessage("test_1","Hello >> world!"); } >> } >> >> or leaving test_1 as you had it before: >> >> test_2.java: >> >> public class test_2 implements PlugIn { >> >> public void run(String arg) { >> test_1 temp = new test_1(); >> temp.shared_method(); >> } >> >> } >> >> The previous test_1/test_2 combination shouldn't have been compilable. >> >> Best, >> Stephan -- Dr Michael Doube BPhil BVSc PhD MRCVS Research Associate Department of Bioengineering Imperial College London South Kensington Campus London SW7 2AZ United Kingdom |
In reply to this post by Bob Loushin
It seems that either Java or ImageJ show us their ugly face here ;)
The path matters! Never thought about this because I always followed the main stream and did that... If test_1 is in package my_stuff, it also has to be in a folder my_stuff respectively. The content of your jar must thus be minimally: $ jar -vtf Test_.jar 471 Tue Jan 19 17:58:14 CET 2010 my_stuff/test_1.class 132 Tue Jan 19 17:40:20 CET 2010 plugins.config Add the source if you like. The jar must have an underscore in its name for announcing itself as a plugin to ImageJ (e.g. Test_.jar) In your example, the package declaration was missing thus the code should be: $ cat my_stuff/test_1.java package my_stuff; import ij.*; import ij.process.*; import ij.gui.*; import java.awt.*; import ij.plugin.*; public class test_1 implements PlugIn { public void run(String arg) { shared_method(); } public void shared_method() { IJ.showMessage("test_1","Hello world!"); } } I compiled that with: $ javac -cp /wherever/you/have/imagej/ij.jar my_stuff/*.java then $ jar cvfM Test_.jar my_stuff/* plugins.config Runs for me. Best, Stephan On Tue, 2010-01-19 at 09:36 -0600, Bob wrote: > Stephan, > > You're right, of course, I should have used a new in my test_2.java example > (it is in the original code, but didn't survive when I rewrote the > simplified illustration). But where I'm stuck is at the point before test_2 > enters the picture. Basically, I can't get experiment 2 (which only > involves the packaged version of test_1) to work. You're also correct that > this may be a Java problem, not an ImageJ problem, since I'm new to both. > To focus a bit more clearly on my current stopper, this fails: > > test_1.java: > package my_stuff; > > import ij.*; > import ij.process.*; > import ij.gui.*; > import java.awt.*; > import ij.plugin.*; > > public class test_1 implements PlugIn { > > public void run(String arg) { shared_method(); } > > public void shared_method() { IJ.showMessage("test_1","Hello world!"); } > } > > > plugins.config: > > # Name: Test_Plugin > > # Author: Bob > # Version: 1.0 > # Date: 1/18/10 > # Requires: ImageJ 1.31s > > Plugins>Test, "Test 1", my_stuff.test_1("run") > > The issue may be in the way I compile, by just using the "Compile and > Run..." in ImageJ to generate test_1.class, and then manually making the > .jar file using "jar cvfM Test.jar test_1.class test_1.java plugins.config". > However, it seems more likely to me that I have the syntax wrong in the last > line of plugins.config. The error message I am getting is: "Plugin or > class not found: 'my_stuff.test_1' (java.lang.ClassNotFoundException: > my_stuff.test_1)" > > > > Your problems are on Java syntax, not ImageJ ;)---read: > > > > http://java.sun.com/docs/books/tutorial/java/index.html > > > > I your case, what you're trying is to use an instance method in a static > > way. In Java, an object is not instantiated just by declaring it, you > > have to use new. So either: > > > > test_1.java: > > > > public class test_1 implements PlugIn { > > > > public void run(String arg) { shared_method(); } > > > > static public void shared_method() { IJ.showMessage("test_1","Hello > > world!"); } > > } > > > > or leaving test_1 as you had it before: > > > > test_2.java: > > > > public class test_2 implements PlugIn { > > > > public void run(String arg) { > > test_1 temp = new test_1(); > > temp.shared_method(); > > } > > > > } > > > > The previous test_1/test_2 combination shouldn't have been compilable. > > > > Best, > > Stephan |
Stephan,
Thank you! It all works now, when I put the path in the .config file. That was the missing piece. Yes, it was a conspiracy--ImageJ forcing things into packages before allowing objects to call one another, and then Java having this subtle issue with paths inside .jar files needing to match the package structure. I really appreciate your help. Bob Subject: Re: Path Problem? > It seems that either Java or ImageJ show us their ugly face here ;) > > The path matters! Never thought about this because I always followed > the main stream and did that... > > If test_1 is in package my_stuff, it also has to be in a folder my_stuff > respectively. The content of your jar must thus be minimally: > > $ jar -vtf Test_.jar > 471 Tue Jan 19 17:58:14 CET 2010 my_stuff/test_1.class > 132 Tue Jan 19 17:40:20 CET 2010 plugins.config > >>SNIP<< |
Hi,
On Tue, 19 Jan 2010, Bob wrote: > Thank you! It all works now, when I put the path in the .config file. > That was the missing piece. Yes, it was a conspiracy--ImageJ forcing > things into packages before allowing objects to call one another, and > then Java having this subtle issue with paths inside .jar files needing > to match the package structure. This cannot stand as you put it. It was a concious design decision of Java to require classes to be put into packages before they can be imported. If you have a class that is in the default package (i.e. none), you can use other classes from that default package, but that is bad style anyway, as there would be too many clashes if everybody did that. And the alternative to letting classes be put into .jar files wherever you like it instead of according to the package would mean an unbearable performance impact. Basically, _every_ _single_ class in _every_ _single_ .jar file would have to be inspected if it might be the one you might look for (remember, you can say "import ij.*;")! So I think that both issues you hit have a very good reason for having to be fixed on your side instead of anywhere else. Ciao, Dscho P.S.: I would be interested to know if there is any Java book out there which fails to mention both that you should put classes into appropriate packages (and why) and that you must put classes into directory structures reflecting the package structure (does not matter whether they are inside a .jar file or in a directory in the classpath). |
Free forum by Nabble | Edit this page |