Adding a Custom Class

How did you add your class to the zip file? The most common cause for this, I think, is not having the correct directory structure inside the zip (a lot of zip utilities like to automatically include the parent directory), but if you dragged new files into an existing zip archive to update it, that shouldn’t happen.

I extracted the contents of the original module zip file to a directory. Then I added my custom class to it. Then I rezipped it. I will try it again by simply dragging the class file into the module zip file. I tried it this way because of the focus in the instructions on getting the full path correct. Perhaps I misunderstood.

Just tried dragging the class file into the module zip file. I get a “The Compressed folder is invalid or corrupted” error message. trying this in Win10 using File Explorer.

When I try to run the module zip file as a .vmod file, it works perfectly. But when I rename it to a .zip file, it won’t let me drag a file into it.

Maybe grab a copy of 7-zip and try using that instead. I’m not familiar with Windows 10’s zip support, but it wouldn’t surprise me if it was a bit crap. It’s kind of a theme I’m seeing in operating systems lately.

7-zip worked. I was able to drag-and-drop the file into the zip .vmod file and then open the zip .vmod file in the VASSAL editor.

So, thanks very much for your help on this. I really appreciate it.

However, I am still having a problem. I am trying to use the Add Imported Class feature to incorporate the class into my game. I am getting a ClassNotFound error. So I suspect I am not giving it the correct full path.

Before adding the custom class to the zip file, I created a directory inside the zip file called “MyGame.module”. This matches the package name for the class which is MyGame.module. The name of the class is Buttons.java. So, when prompted for the full path name to add the imported class, I type MyGame.module/Buttons.java. And get the ClassNotFound error. Can you see where I am making a mistake in the path?

Thanks

Try just the java name: MyGame.module.Buttons

However, I think you need to use two directories rather than one with a dot in it. I could be mistaken, but if the above name also doesn’t work, try structuring it in the module as MyGame/module/Buttons.java.

[Edit] Buttons.class, not Buttons.java, sorry.

Yes, the directory structure within the module must match the package
name structure.

So inside your module there will need to be a directory named MyGame,
which must contain a directory named module, which must contain the
compiled Buttons.class file.

You would then enter the fully qualified name of the class which is
Mygame.module.Buttons

Regards,
Brent.

On 12/11/2019 9:25 am, Malnorma wrote:

[This message has been edited.]

Try just the java name: MyGame.module.Buttons

However, I think you need to use two directories rather than one with a
dot in it. I could be mistaken, but if the above name also doesn’t
work, try structuring it in the module as MyGame/module/Buttons.java.

[Edit] Buttons.class, not Buttons.java, sorry.


Read this topic online here:
https://forum.vassalengine.org/t/adding-a-custom-class/10079/9


messages mailing list
messages@vassalengine.org
vassalengine.org/mailman/listinfo/messages


Brent Easton
Analyst/Programmer
Western Sydney University
Email: b.easton@exemail.com.au


messages mailing list
messages@vassalengine.org
vassalengine.org/mailman/listinfo/messages

[quote=“Brent Easton”]
Yes, the directory structure within the module must match the package
name structure.

So inside your module there will need to be a directory named MyGame,
which must contain a directory named module, which must contain the
compiled Buttons.class file.

You would then enter the fully qualified name of the class which is
Mygame.module.Buttons

Regards,
Brent.

Thanks to you both for your continued help. I tried MyGame.module.Buttons and got a different error message: “There was an error loading or instantiating the class WingLeader.module.Buttons, which is provided by this module.”

I assume that this means that MyGame.module.Buttons worked in that the class was found but that there is an error in the class. I created the class based on the programming example on the site, with the addTo method creating two buttons which is just what I needed my class to do. I have not added the Buttons class to the buildfile in the .vmod - I assumed that this would happen if it was successfully added by the Editor. I was trying to add the class to the Main Map window as it’s purpose is to put two buttons on the toolbar. Should I try elsewhere?

Is the class actually supposed to be named WingLeader.module.Buttons? i.e. in your code, do you have:

package WingLeader.module; public class Buttons { ... }

If so, you should rename the MyGame folder to WingLeader and use the name WingLeader.module.Buttons instead. If WingLeader.module.Buttons is in another class file entirely, you’ll need to add it to the module as well (and any other related classes). If there’s a problem instantiating your class, you’ll need to either debug it or check Vassal’s log to try and understand where it went wrong.

If you’re willing to share the code you’ve written, you’ll probably get more useful comments :slight_smile:

Sorry about that. The project I am working on is WingLeader. I generally use a generic name rather than the particular name when asking of help because sometimes the exact names can cause confusion in and of themselves. But maybe I am wrong about that. Using a generic name certainly caused confusion this time.

Here is the VASSAL log I am getting with this recent error message. You will see it uses yet another different package name as I have tried to simplify the path by getting rid of the “.module”.

I have tried this with a directory structure of src\WingLeader\Buttons.java and with WingLeader\Buttons.java (without changing the package name). Neither work. I have tried using Buttons, Buttons.class and Buttons.java as the file name.

As you can see, the problem is still that VASSAL can’t seem to find the imported class. Thanks again for your help.

java.lang.ClassNotFoundException: Unable to load class WingLeader\Buttons
at VASSAL.tools.DataArchive.findClass(DataArchive.java:453)
at VASSAL.tools.DataArchive.loadClass(DataArchive.java:424)
at java.lang.ClassLoader.loadClass(Unknown Source)
at VASSAL.configure.ConfigureTree.importConfigurable(ConfigureTree.java:849)
at VASSAL.configure.ConfigureTree$5.actionPerformed(ConfigureTree.java:465)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: java.io.FileNotFoundException: ‘WingLeader\Buttons.class’ not found in C:\Users\dougr_000\Documents\Programming Documents\almodule\WL v4 LAYER TEST.vmod
at VASSAL.tools.DataArchive.getInputStream(DataArchive.java:240)
at VASSAL.tools.DataArchive.findClass(DataArchive.java:449)
… 42 more

I think if you show them your source file, they can tell you exactly where the compiled class has to go in the module.

I have tried this with a directory structure of src\WingLeader\Buttons.java and with WingLeader\Buttons.java (without changing the package name). Neither work. I have tried using Buttons, Buttons.class and Buttons.java as the file name.

The *.java file is the (plaintext) source file. It doesn’t go into the module. When you compile the class, foo.java is turned into foo.class (and perhaps other files if there is more than one class in the source file). That *.class file is what you need to put into the module. You do not want to rename anything. You do need to compile your source into a class.

As zgrose said, but the exact name of the class (package + class name) should match the directory structure too. You can’t pick the name afterwards without changing the source.

So if you have:

package WingLeader;
class Buttons { ... }

then you need to use the path WingLeader/Buttons.class

Thanks for your continuing help on this. I had to step away from it for a few days and work on some other stuff. But I hope to crunch this problem now.

I have added the Buttons.java file to my module using 7-Zip.

When I show the properties for Buttons.java, I get the following:

Name: WingLeader
Path: C:\Users\dougr_000\Documents\Programming Documents\almodule\WL v4 LAYER TEST.zip

When I look within the Buttons.java file, I see

package WingLeader;

import VASSAL.build.AbstractConfigurable;
import VASSAL.build.Buildable;
import VASSAL.build.GameModule;
. . . .

That all seems to line up properly.

When I rename the .zip file to .vmod and then try and edit the module in VASSAL, I continue to get a file not found error relating to buttons.class.

I have now tried taking a compiled version of Buttons, named Buttons.class, and adding that directly to the .vmod file using 7-Zip.

Again, it all appears to have the right path and names, but I get the same class not found error.

What other information would be helpful to you?

It’s not clear to me if you’ve included the folder in the zip file, but you do need to - put your Buttons.class file in a folder called WingLeader, and then drag the WingLeader folder to the module in 7-zip.

Yes, I had done. I created the folder WingLeader in 7-Zip then dragged Buttons.class into the folder in 7-Zip.

[attachment=0]7zip.PNG[/attachment]

OK, all good - so in the Vassal editor, when you right-click and choose to add custom class, you enter “WingLeader.Buttons” and it complains that it can’t find the class? If so, would you be willing to make the vmod file available to download temporarily?

Yes, whether I use WingLeader.Buttons or WingLeader.Buttons.class or WingLeader/Buttons.class, I get the same message.

Happy to share the .vmod. How best to make it available?

Here is a link to the .vmod in dropbox: dropbox.com/s/s84s7mjo9xese … .vmod?dl=0

You should be able to download it from there.

So, going forward you don’t need to include Buttons.java in the folder. It doesn’t hurt, but won’t achieve anything either. But since you did, I noticed that it contains some additional class definitions. I believe when you compile this file, there will be other class files generated - you probably need to include these files in that folder as well. Any file that starts with Buttons and ends in .class; I think there should be three of them besides the one already included.

Thanks for this. I appreciate your help.

Added all the versions of Buttons to the .vmod file with 7-Zip. No change. Same error.

When I drag and drop Buttons into the .vmod file, are there any properties or settings that might be getting in the way?

Could you upload that version of the vmod to dropbox as well? I tried compiling the java file here and adding the class files to the module, and was able to add WingLeader.Buttons successfully (I don’t think the class is working quite right yet, but I was able to add the custom class and it did something to the toolbar).

There were five total class files in the WingLeader folder:
Buttons$1.class
Buttons$2.class
Buttons$HideMarkers.class
Buttons$HideTargets.class
Buttons.class