Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

How to Add JARs to a JetBrains MPS Project

DZone's Guide to

How to Add JARs to a JetBrains MPS Project

JetBrains MPS is a handy tool for creating DSLs, among other things. Let's see how you can add JAR files to your MPS projects.

· Java Zone ·
Free Resource

Verify, standardize, and correct the Big 4 + more– name, email, phone and global addresses – try our Data Quality APIs now at Melissa Developer Portal!

JetBrains MPS is a wonderful tool to create DSLs. We love it and use it regularly in our consultancy work, and we have written about JetBrains MPS before.

Being a projectional editor, it allows you to easily create DSLs that can be used through a graphical interface or things like mathematical formulas, though all this power requires a bit of preparatory work.

One of the most important characteristics of MPS is the fact that it permits the reuse of Java code. New Java code can be written in MPS through what it is called the BaseLanguage. However, sometimes, we want just to reuse existing Java code inside MPS.

In this tutorial, we are going to see:

  1. How you can load JARs into MPS
  2. How we use this feature to solve a common problem: loading static resources with Java to use them in JetBrains MPS code.

First, we will see how to create a new JAR containing resources and then how to load an existing JAR into JetBrains MPS.

Creating a JAR Containing Static Resources

We are going to use a Gradle script to create the JAR because it is more convenient and can be easily automated — but obviously, you can do it the way you prefer.

The structure of the project is a traditional Java one, with resources and src directories.

Resources project

The Gradle project is simple — all we need to do is create the build.gradle file with the following content.

build.gradle:

apply plugin: 'java'

sourceSets.main.resources.srcDirs = [ "resources/" ]
sourceSets.main.resources.includes = [ "**/*.png", "**/*.gif" ]


All we did is indicating where to find the resources and which files to include, in our case image files for icons.

The Java class is equally trivial. We make the icons accessible as static fields.

ExamplesIcons.java:

package com.strumenta.examples.icons;

import javax.swing.*;

public class ExamplesIcons {
    
    public static final ImageIcon MAIN;
    public static final ImageIcon CIRCLE;    

    static {
        MAIN = createImageIcon("/com/strumenta/examples/icons/main.png", "Main Icon");
        CIRCLE = createImageIcon("/com/strumenta/examples/icons/circle.png", "Circle Icon");
    }

    private static ImageIcon createImageIcon(String path, String description) {
        java.net.URL imgURL = ExamplesIcons.class.getResource(path);
        if (imgURL != null) {
            return new ImageIcon(imgURL, description);
        } else {
            System.err.println("Icon not loaded: " + path);
            return null;
        }
    }
}


Since we are building icons, we need to import the proper Javax Swing dependency.

Now, we enter the main directory of the Gradle project and build it.

# Linux/Mac OS/Cygwin
./gradlew jar
# Windows
./gradlew.bat jar


The end result should be a resources_project.jar under the build/libs/ directory.

The MPS Project

Now that we have our JAR with the icons, we must make it accessible to MPS code. You can use the same procedure with any existing JAR code that you have.

We prefer to import static resources in their own solution because it makes the project cleaner. So, we start by creating a solution called com.strumenta.examples.external, which generates a directory with that name and an .msd file of the same name. Inside the directory, there will also be a models directory. Inside the com.strumenta.examples.external directory, we manually add a libs directory with our resources_project.jar.

MPS Solution with the libs directory

We still have to add the generated library to the module by going to Module Properties (Alt + Enter).

  1. In the Dependencies tab, we add the JDK module and then select Export:MPS dependencies
  2. In the Java tab (Libraries section), we add the JAR file. In MPS, you will see the complete path, but internally, MPS is saving a relative path because we inserted the JAR in the solution directory. This is very important because it means that other contributors working on the project on other machines will get the right result even if they put the project in a different path:MPS Java libraries
  3. In the Common tab, we click Add Model Root->java_classes, then we select the JAR file in the right panel and click Sources to add its content to the modelsMPS Java classes

If your libraries need third-party Java code, you should perform steps 2 and 3 for your dependencies. In our case, we do use third-party code (Javax Swing), but it is part of the JDK platform already included. So, we do not need to do anything else.

In a real-world scenario, the issue is that there might be a lot of dependencies, especially for complex projects. So, you might want to first collect all the dependencies using a standard tool, like Gradle or Maven, and then insert them in MPS.

If you open the ExampleIcons file now, you should see something similar to the following image:
MPS external solution
If you see some errors in ExamplesIcons, you probably added things in the wrong order. You have to add the JDK module first so that MPS can automatically add what is needed. To confirm that everything is working okay, you can also look at the Model Properties of the icons@java_stub model. It should have automatically included both Java and Javax.Swing among its dependencies (you cannot add them manually).

MPS dependencies model

To test the inclusion, you can use the MPS Console. Use CTRL+M to include the external solution and then try the command printText with the instruction ExamplesIcons.MAIN.getDescription(), as in the following image. Then press the Execute button: It should print “Main Icon”:
MPS console

And that is basically it. You just have to remember to include the module com.strumenta.examples.external as a dependency for each module in which you use the code included in the JAR. If you want to use the resources in a plugin or a simulator, you may want to add it as a runtime dependency.

Include the JAR in Build Models

If you generate plugins or custom versions of MPS, you are going to use build models. In that case, you should add your JAR in those build models.

For instance, if you generate a plugin, you have to copy the JAR into the directory of the plugin, as in the following image:

MPS plugin

If you forgot to do that, you will receive an error when you try to generate a model related to the build of the plugin.

Developers! Quickly and easily gain access to the tools and information you need! Explore, test and combine our data quality APIs at Melissa Developer Portal – home to tools that save time and boost revenue. 

Topics:
java ,jetbrains mps ,jar files ,tutorial

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}