# Element Structure

Starting with Elements 3.0, we are now providing a way to develop custom extensions in Java Virtual Machine (or JVM) based languages. Refer to the [Wikipedia](https://en.wikipedia.org/wiki/List_of_JVM_languages) page for a complete list and determine the best language which works for your project. The most popular choices are Java and Kotlin. Elements is natively written in Java which is 100% compatible with any other JVM based language.

We call our fundamental plug-in an Element. Each Element runs in an isolated environment using a [ClassLoader](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/ClassLoader.html) which isolates Element from the rest of the system. A common problem Java developers face is conflicting dependencies within a single application, colloquially known as "[Jar Hell.](https://en.wikipedia.org/wiki/Java_class_loader#JAR_hell)"

Our approach allows you to use develop in an environment without having to worry about conflicts between the Elements 3.0 code base and your Element's code. We provide a set of interfaces, but isolate their implementations from your code. When developing an Element, these are the key points you must know:

* You can incorporate almost any existing Java code base into Elements that are based on standard Java frameworks. Elements 3.0 Currently Supports:
  * Jakarta RS 4.0.0
  * Jakarta Websockets 2.1.0
* You can include almost any third-party library into your code base without having to worry about it conflicting with the frameworks used to build Elements
  * Note: You will need to copy all dependencies into your Element, except those as provided by Elements 3.0.
* An Element does not have strict isolation, nor does it run in a sandbox. This is by design, as trying to enforce strong encapsulation using a Security Manager (or similar) would introduce a lot of overhead for no benefits. Take special care when accessing the [System ClassLoader](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/ClassLoader.html#getSystemClassLoader\(\)).

### Defining an Element

An Element exists as a Java package and, optionally, include all sub-packages recursively. Elements are similar to [JPMS Modules](https://www.oracle.com/corporate/features/understanding-java-9-modules.html) but without the one jar per module restrictions.

The following example shows how to define an Element in your Java code. Note we do require that you define a `package-info` for the package. The following is the simplest Element possible.

{% code title="package-info.java" %}

```java

// Defines the Package. Specifies as recursive.
@ElementDefinition(recursive = true)
package com.mystudio.mygame.api;

// Imports the Element SDK Annotation
import dev.getelements.elements.sdk.annotation.Element
```

{% endcode %}

This indicates that the package `com.mystudio.mygame.api`and all sub packages will be included in the Element for associated services.

### Packaging an Element

Packaging an Element or collection of Elements uses a simple directory structure. Elements 3.0 will search for the following files and directories when loading the assets associated with an Element:

* `dev.getelements.element.attributes.properties` - A standard [Java Properties](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Properties.html) file which define the Element's application
* `libs` - A directory containing jar files. The loader scans the directory for jar files and adds them to the Element's classpath.
* `classpath` - A directory containing assets to add directly to the Element's classpath.

Additionally, the following rules apply when scanning a directory for Elements.

* Any file not otherwise specified would be ignored.
* Any directory will be treated as a new Element, provided that that at least `libs` or `classpath` exist.
  * **Note:** Elements defined in directories will inherit the classpath of the parent which allows you to put common code in the parent directory.
