The Jamal Maven Load module contains a macro to download Java JAR files from Maven repositories during run-time and load the macro classes into the running application.
I designed the library’s security, balancing the ease of use and the application’s security. Without security measures, a Jamal file could execute any Java code published online, which is not a good idea. The Jamal installation has to be adequately configured to use this module. The requirements of a proper configuration are described in the section about security.
Currently, there is only one macro defined in this module.
It loads the macros from a Maven artifact and its dependencies unless the noDependencies
option is used.
This macro reads its input and interprets it as a maven coordinate set. The format has to be
groupId:artifactId:version
You have to specify all three coordinates. The macro works in two steps:
-
First, it downloads the artifact JAR and all the dependencies.
-
Using a class loader, it loads the macros from the JAR files (the specified one and the dependencies).
Loading only the file without the dependencies is possible using the noDependencies
option.
Warning
|
Loading a JAR file from the internet is a security risk. You must configure the security appropriately to mitigate this risk. For more information, see the section about security. |
The behavior of the macro can be controlled using options.
The options should follow the macro’s name between (
and )
characters.
The options are:
-
repositories
(aliases arerepository
,repo
,repos
) define the Maven repositories used comma separated. The values are the repository URLs or symbolic names. The symbolic names can be-
central
-
jcenter-bintray
-
google-android
-
google-maven-central-americas
-
google-maven-central-europe
-
google-maven-central-asia
The default value is
central
. When a URL is specified, it is checked against the configuration. The symbolic names are permitted by default; they can be used without configuration. URLs must be configured in themaven.load.repo
configuration property. For more information, see the section about security.
-
-
noDependencies
(alias isnoDeps
) says that the dependencies of the JAR should not be loaded. The default value isfalse
. -
reload
(aliases areoverwrite
,update
) says that macros found in the JAR should be reloaded even if they were already loaded. -
local
can specify the location of the local Maven repository. The default value is~/.m2/repository
. If this option is used, it is checked against the configuration. For more information, see the section about security. -
exclude
can specify a comma-separated list of maven coordinates that should not be loaded. This parameter will not stop loading the "root" artifact specified in the macro input. The coordinates format is the same as in the configuration file for themaven.load.exclude
property regarding the wildcards.
If the configuration or the security prevents the load, the macro throws an IllegalStateException
.
It means that the processing will stop.
Also, it is impossible to catch and handle this error using the {@try …}
macro.
The macro maven:load
reads the configuration of Jamal via an API that works only when the configuration is secure.
This macro works only if your configuration files' access control is set correctly. Without that, someone accessing the computer in a different account could modify the configuration, potentially loading malicious code.
The configuration must be secure, meaning:
-
There is no configuration. In that case, nothing can be opened, so there is no security risk. However, in this case, the macro cannot load any JAR file. OR
The configuration directory and the files are SAFE
-
~/.jamal
, and the files -
~/.jamal/settings.properties
, and -
~/.jamal/settings.xml
are SAFE
A file or directory is SAFE if
-
it does not exist, or
-
owned by the current user and
-
not writable by anyone else, and
-
not readable by anyone else,
-
not listable (
x
flag) by anyone else. -
In the case of a plain file, it is not executable (
x
flag) by anyone, including the current user. -
It is a plain file when it is supposed to be a file, and it is a directory when it is supposed to be a directory.
When reading the configuration, if any of the
-
maven.load.include
-
maven.load.exclude
-
maven.load.local
-
maven.load.repo
properties point to files; these files should also be SAFE.
Note
|
Securing the configuration is not a must for Jamal’s other parts and functionalities, although it is a good practice.
The security is only checked before reading the configuration for the maven:load macro.
|
Also, the maven:load
macro uses a unique API to read the configuration.
Every time the macro runs, the API rereads the files, checks the security of the configuration, and ignores the in-memory cached configuration.
Also, note that while most of the macros and functionalities of Jamal read configuration via an API that consults the system properties first, environment variables second, and lastly, only
the configuration files,
the API used by the maven:load
macro reads only the configuration files in the directory ~/.jamal/
.
These are ~/.jamal/settings.properties
or ~/.jamal/settings.xml
.
Note
|
When Jamal is executed in an interactive environment the security for a specific It also means that changing the configuration to prevent the load of a macro library that was already loaded is futile. On the other hand, changing the configuration to allow the load of a macro library that failed to load due to security settings is effective. There is no need to restart the application executing Jamal. |
The maven:load
macro has to be configured for security reasons.
It can only load JAR files which are explicitly allowed by the configuration.
Also, the remote and local repositories must be configured unless the well-known hardwired repositories are used with the default local location.
The values for the property keys are
-
comma-separated list of maven coordinates + path,
-
absolute paths,
-
URLs, or
-
a file name that contains the list of the same information.
When a key points to a file, the file also has to be SAFE as defined in the previous section. It has to be in the same directory as the configuration file and has to be specified by the bare name and extension but without any path. The file contains the configuration information, one per line.
Note
|
You can use the comma-separated list in the |
The configuration should always have the property maven.load.include
set.
The property gives the list of permitted maven coordinates.
Every maven coordinate has to be in the format
groupId:artifactId:version
or
groupId:artifactId:version:path
The groupId
cannot be a wildcard.
The artifactId
and version
may be a wildcard *
.
The path part is optional.
If the artifactId
is a wildcard, then the version
has to be a wildcard too.
The path represents the path to the Jamal source.
It can be the absolute path to the Jamal input file or the directory containing one or more Jamal input files.
If the path is a directory, maven:load
is also permitted for all subdirectories.
When the value ends with a /
, it is considered a directory.
When the path is specified, it is compared against the path of the Jamal source. The Jamal source file has to be the same or has to be in the specified directory.
The macro maven:load
is sometimes used from a file included or imported by the top Jamal source directly or through other includes or imports.
In this case, the path of the top-level Jamal file is used only.
The key maven.load.exclude
can exclude some maven coordinates from the list of allowed coordinates.
If a coordinate is excluded, it cannot be used even if included in the maven.load.include
list.
A coordinate will also be skipped if one is present as a dependency. In this case, however, the download will not stop. The class loading, however, may still fail if classes are missing because of the exclusion.
The key maven.load.local
can be used to specify the location of the local Maven repository.
It has to be configured when the option local
is used.
The values have to specify the absolute paths of the allowed directories that can be used as local repositories.
Warning
|
This is a security configuration. Specifying a location here will not change the default location. It merely lists the allowed locations. |
The key maven.load.repo
can be used to specify the list of allowed remote repositories in addition to the predefined ones.
The values must be the URLs appearing in the repositories
option of the maven:load
macro.
Warning
|
This is a security configuration. Specifying a URL here will not change the default repository. It merely lists the allowed repositories. |