Resource [GUIDE] Windows - Extremely productive development environment

Discussion in 'Spigot Plugin Development' started by PiggyPiglet, Sep 7, 2019.

  1. Before I get started, please note this guide is specifically made for IntelliJ. The same concepts may be achievable in other IDE's, but I don't know how. Also, sorry in advance for how many images, but I feel they're necessary, as when I've tried to explain this process in the past, people simply couldn't find the options I was referring to.

    First, there are a couple of things you'll need to install. In IntelliJ, download the HotswapAgent plugin, and the Run Configuration as Action plugin. The latter allows us to bind maven/gradle tasks to a button, which can then be binded to a keybind.

    You'll also need DCEVM. Assuming you're using HotSpot, the default hotswapping capabilities of are extremely limited, restricting you to only being able to hotswap method bodies. DCEVM greatly improves upon this, by allowing you to hotswap nearly anything. DCEVM can either be added onto an existing JDK (<8), or fully replace the JDK (<11). I'm going over the latter in this guide, but the former isn't necessarily difficult to achieve either.

    Download the latest binary zip from here, then extract it into C:\Program Files\Java\. Your directory tree should look something like this after:

    You may be wondering, why not jRebel? Simple fact is, the company behind them are extremely greedy, and do not offer free licenses, or even discounted ones anymore. It's not exactly affordable either iirc, and while hotswapping is extremely useful, jrebel's price just isn't justifiable. So, while DCEVM isn't as supported, probably isn't as stable, and may have unknown semantics, it's really the only option available to your average hobbyist developer.

    We can now move onto actually setting up the IDE. The first step, is creating your build task. If using maven, click on ADD CONFIGURATION in the top right corner of your screen.
    In the window that opens, click the + in the top left, and select Maven
    I'd recommend just calling it Package, but it's entirely up to you. Set the Command line to package
    You can then click Apply and then OK at the bottom right.

    If using gradle, executing a task will automatically create a configuration for you. For example, running shadowJar will automatically create a shadowJar configuration.
    Upon completion and validation that the configuration is working, press control + alt + s to open up settings. Then navigate to the Appearance & Behaviour section, and click Menus and Toolbars.
    Find and open the Navigation Bar Toolbar dropdown, and figure out where you want to position the item. I usually put mine after Run anything. Simply highlight the element that's above the position you wish to place your icon in, then click the + at the top of the window, and select Add Action
    Open Plug-ins > Run Configuration as Action, and find your task.
    If you deem it necessary, you can set an icon like I've done myself, however it's purely cosmetic. Click on the task, then click OK. Verify that the icon is on your toolbar, by clicking Apply and OK in the bottom right corner of your Settings window, then looking for the icon. If it's there, open settings back up with ctrl + alt + s, then open the keymap section.
    Navigate to Plug-ins > Run Configuration as Action > your task, right click on it, and add keyboard shortcut. I personally use ctrl + b, but it's up to you. Once set, in the search box in the top right, search Reload Changed Classes. Add a binding for Main menu > Run > Reload Changed Classes. I personally use alt + r.
    Lovingly caress the Apply and OK buttons, and verify your build keybind is working. We'll test alt + r later. For absolute maximum efficiency, I'd recommend configuring your build tool to automatically output the jar into your test server's plugin folder. Speaking of test servers, let's set one up.

    Actually... not so fast, before we can do that, we need to set our JDK. Open project structure (control + shift + alt + s), and click project. Then, click new in the Project SDK section. Navigate to the path your dcevm installation is at, and add it. Then select said installation. Also change the project language level to 11.
    Once again, hit apply and ok.

    Ok, now we can create the test server. Create a new folder in your projects root directory, and call it whatever you want, then put your spigot jar in. Click on the top right, where your configurations are, and add a new configuration. Set it to Jar Application.
    Fill it out with the path to your jar, and the directory your jar is in. If you wish, you can add -DIReallyKnowWhatIAmDoingISwear as a VM option, which will stop the outdated spigot warning from showing. Set the JRE to the one we added before.
    Apply & OK. Verify the server is working by starting it, and accepting the eula ofc. Let it run through it's world gen stage, then stop is via the proper command. Believe it or not, that was the last stage, everything is ready now.

    Set your current configuration to the spigot server. You'll be able to run this with shift + f9, and build the plugin with whatever bind you set earlier. If the server is running and you've changed the code, use your reload keybind to hotswap.

    Attached Files:

    #1 PiggyPiglet, Sep 7, 2019
    Last edited: Apr 2, 2020
    • Useful Useful x 9
    • Like Like x 5
    • Funny Funny x 1
  2. Benz56

    Moderator Supporter

    Very nice, detailed, and extensive tutorial - kudos!

    For all of you who do not want to set all of this up, I personally recommend BileTools. It'll automatically detect when you build your plugin in you IDE and swap it for you instantly while the server is running.
    • Agree Agree x 2
    • Informative Informative x 2
  3. BileTools looks cool, but I don’t think it’s a replacement for DCEVM. For example, imagine you’re in a delicate situation, where you’ve got objects stored in memory that aren’t easily reproducible. With dcevm, no problem, just add the code to interact with it. Such objects would be lost with biletools though.
    • Informative Informative x 1
  4. Benz56

    Moderator Supporter

    You're completely right! I forgot to mention that BileTools reloads the entire plugin and not just a segment of it. Haven't encountered such a situation yet though, but sure, it might be useful for some to have persistence between builds.
  5. Trying this on the latest Intellij with Spigot, Reload Changed Classes does nothing.

    Looks cool if I could get it to work though!

    EDIT: I think I just need to run it in Debug mode.
    #5 Big_Bad_E, Sep 14, 2019
    Last edited: Sep 15, 2019
  6. Hello, I am trying to set this up and have followed your guide to the end. Unfortunately I get the error of "Hot swap failed" as seen here this is when running what you have set to "alt+r". Any help is appreciated :) The server is running and the package is built successfully.
  7. Are you using any sort of relocation? That error is usually caused when your build tool (maven or gradle) is doing relocations, or if you're relocating classes at runtime. Hotswapping doesn't use your build tool, resulting in an internal inconsistency regarding class names/packages.
    #7 PiggyPiglet, Sep 15, 2019
    Last edited: Sep 15, 2019
  8. Thanks for this! Will try to set this up when I get some free time and return with results :)
  9. Hey, sorry for necroposting.
    I am using Java 8, and the only way I found to install DCEVM in Java 8 is using the installer, selecting the jdk and clicking "install as altjdk", which then makes me use -XXaltjvm=dcevm flag.
    When I run the server through the configuration (I also added the nogui flag), I get this output:
    Code (Text):
    "C:\Program Files\Java\jdk1.8.0_251\jre\bin\java.exe" -XXaltjvm=dcevm -Dfile.encoding=windows-1255 -jar C:\Users\Robert\IdeaProjects\PLUGIN_NAME\server\spigot-1.15.2.jar --nogui
    Error occurred during initialization of VM
    Unable to load native library: The specified procedure could not be found
    I tried running the command above in the command prompt and I get the following message in a pop-up:
    Code (Text):
    The procedure entry point JVM_CopySwapMemory could not be located in the dynamic link library jvm.dll.
    along with this message in the command prompt:
    Code (Text):
    Error occurred during initialization of VM
    Unable to load native library: The specified procedure could not be found
    Any help is appreciated :D
    #9 robertlit, May 28, 2020
    Last edited: May 28, 2020