Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/cicd_comp_test-phase.yml
Original file line number Diff line number Diff line change
Expand Up @@ -187,5 +187,3 @@ jobs:
needs-docker-image: ${{ matrix.needs_docker == true }}
github-token: ${{ secrets.GITHUB_TOKEN }}
artifacts-from: ${{ env.ARTIFACT_RUN_ID }}


2 changes: 1 addition & 1 deletion .sdkmanrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# sets the SDKMAN_JAVA_VERSION for dotCMS
# this is the version of java that will be used as the base image for the docker build
java=21.0.8-ms
java=25.0.1-ms
27 changes: 15 additions & 12 deletions bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@
<aws-java-sdk.version>1.12.488</aws-java-sdk.version>
<twelvemonkeys.version>3.10.1</twelvemonkeys.version>
<swagger.version>2.2.34</swagger.version>
<bytebuddy.version>1.14.15</bytebuddy.version>
<bytebuddy.version>1.18.1</bytebuddy.version>
<batik.version>1.17</batik.version>
<bouncy-castle.version>1.70</bouncy-castle.version>
<awaitility.version>4.0.0</awaitility.version>
<shedlock.version>4.33.0</shedlock.version>
<jackson.version>2.17.2</jackson.version>
<jersey.version>2.28</jersey.version>
<graalvm.version>22.3.3</graalvm.version>
<jersey.version>2.47</jersey.version>
<graalvm.polyglot.version>25.0.1</graalvm.polyglot.version>
<micrometer.version>1.13.10</micrometer.version>

</properties>
<dependencyManagement>

Expand Down Expand Up @@ -1592,12 +1593,12 @@
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.12.0</version>
<version>5.20.0</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>5.12.0</version>
<version>5.20.0</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down Expand Up @@ -1634,21 +1635,23 @@

<!-- Graalvm Js Engine -->
<dependency>
<groupId>org.graalvm.sdk</groupId>
<artifactId>graal-sdk</artifactId>
<version>${graalvm.version}</version>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>polyglot</artifactId>
<version>${graalvm.polyglot.version}</version>
</dependency>
<dependency>
<groupId>org.graalvm.js</groupId>
<groupId>org.graalvm.polyglot</groupId>
<!-- Select language: js, ruby, python, java, llvm, wasm, languages -->
<artifactId>js</artifactId>
<version>${graalvm.version}</version>
<version>${graalvm.polyglot.version}</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js-scriptengine</artifactId>
<version>${graalvm.version}</version>
</dependency>
<version>${graalvm.polyglot.version}</version>

</dependency>
<!-- AI -->
<dependency>
<groupId>com.knuddels</groupId>
Expand Down
2 changes: 1 addition & 1 deletion docker/java-base/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ FROM ubuntu:24.04 AS base-builder
WORKDIR /srv

# Defining default Java version, can be any java version provided by sdkman
ARG SDKMAN_JAVA_VERSION="21.0.8-ms"
ARG SDKMAN_JAVA_VERSION="25.0.1-ms"

ENV JAVA_OUTPUT_DIR="/java"
ENV DEBIAN_FRONTEND=noninteractive
Expand Down
45 changes: 41 additions & 4 deletions dotCMS/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1376,18 +1376,19 @@

<!-- Graalvm Js Engine -->
<dependency>
<groupId>org.graalvm.sdk</groupId>
<artifactId>graal-sdk</artifactId>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>polyglot</artifactId>
</dependency>
<dependency>
<groupId>org.graalvm.js</groupId>
<groupId>org.graalvm.polyglot</groupId>
<!-- Select language: js, ruby, python, java, llvm, wasm, languages -->
<artifactId>js</artifactId>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js-scriptengine</artifactId>
</dependency>

<!-- AI -->
<dependency>
<groupId>com.knuddels</groupId>
Expand Down Expand Up @@ -1916,6 +1917,40 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<!-- First execution: Process annotations to generate immutable classes -->
<execution>
<id>process-annotations</id>
<phase>generate-sources</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<!-- Include both main and enterprise sources for annotation processing -->
<compileSourceRoots>
<compileSourceRoot>${basedir}/src/main/java</compileSourceRoot>
<compileSourceRoot>${basedir}/src/enterprise/java</compileSourceRoot>
</compileSourceRoots>
<!-- Only process annotations, don't fail on errors from missing generated classes -->
<proc>only</proc>
<annotationProcessors>
<annotationProcessor>org.immutables.processor.ProxyProcessor</annotationProcessor>
</annotationProcessors>
</configuration>
</execution>
<!-- Second execution: Normal compilation with generated sources available -->
<execution>
<id>default-compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<!-- Disable annotation processing in this phase since it was already done -->
<proc>none</proc>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
Expand All @@ -1930,6 +1965,8 @@
<configuration>
<sources>
<source>${basedir}/src/enterprise/java</source>
<!-- Add generated immutable classes to source path -->
<source>${project.build.directory}/generated-sources/annotations</source>
</sources>
</configuration>
</execution>
Expand Down
97 changes: 29 additions & 68 deletions dotCMS/src/main/java/com/dotcms/rendering/js/JsEngine.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.dotcms.rendering.js;

import static com.dotmarketing.util.VelocityUtil.getBasicContext;

import com.dotcms.api.vtl.model.DotJSON;
import com.dotcms.rendering.JsEngineException;
import com.dotcms.rendering.engine.ScriptEngine;
import com.dotcms.rendering.js.JsContext.Builder;
import com.dotcms.rendering.js.proxy.JsProxyFactory;
import com.dotcms.rendering.js.proxy.JsRequest;
import com.dotcms.rendering.js.proxy.JsResponse;
Expand All @@ -22,28 +25,11 @@
import com.dotcms.util.ReflectionUtils;
import com.dotmarketing.business.APILocator;
import com.dotmarketing.business.CacheLocator;
import com.dotmarketing.exception.DotRuntimeException;
import com.dotmarketing.util.Config;
import com.dotmarketing.util.Logger;
import com.liferay.util.FileUtil;
import com.oracle.truffle.api.object.JsDynamicObjectUtils;
import com.oracle.truffle.js.lang.JavaScriptLanguage;
import com.oracle.truffle.js.runtime.GraalJSException;
import com.oracle.truffle.js.runtime.builtins.JSErrorObject;
import com.oracle.truffle.js.runtime.builtins.JSPromise;
import com.oracle.truffle.js.runtime.builtins.JSPromiseObject;
import io.vavr.Lazy;
import io.vavr.control.Try;
import org.apache.commons.lang3.StringUtils;
import org.apache.velocity.tools.view.context.ChainedContext;
import org.apache.velocity.tools.view.context.ViewContext;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.HostAccess;
import org.graalvm.polyglot.Source;
import org.graalvm.polyglot.Value;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.Reader;
Expand All @@ -55,26 +41,33 @@
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.dotmarketing.util.VelocityUtil.getBasicContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.velocity.tools.view.context.ChainedContext;
import org.apache.velocity.tools.view.context.ViewContext;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.HostAccess;
import org.graalvm.polyglot.Source;
import org.graalvm.polyglot.Value;

/**
* Js script engine implementation
* @author jsanca
*/
public class JsEngine implements ScriptEngine {

private static final String ENGINE_JS = JavaScriptLanguage.ID;

public static final String DOT_JSON = "dotJSON";
public static final String WEB_INF = "WEB-INF";
private static final String JS_ENGINE = "js";
private final JsFileSystem jsFileSystem = new JsFileSystem();
private final JsDotLogger jsDotLogger = new JsDotLogger();
private final Map<String, Class<? extends JsViewTool>> jsRequestViewToolMap = new ConcurrentHashMap<>();
private final Map<String, JsViewTool> jsAplicationViewToolMap = new ConcurrentHashMap<>();

private final Lazy<Boolean> allowAllHostAccess = Lazy.of(()-> Config.getBooleanProperty("ALLOW_ALL_HOST_ACCESS", false));
private final Lazy<Boolean> allowAllHostAccess = Lazy.of(
() -> Config.getBooleanProperty("ALLOW_ALL_HOST_ACCESS_JSENGINE", false));

public JsEngine () {
try {
Expand Down Expand Up @@ -133,7 +126,7 @@ public <T extends JsViewTool> void removeJsViewTool(final Class<T> jsViewTool) {
private Context buildContext () {

final Context.Builder builder =
Context.newBuilder(ENGINE_JS)
Context.newBuilder(JS_ENGINE)
.allowIO(true)
.allowExperimentalOptions(true)
.option("js.esm-eval-returns-exports", "true")
Expand All @@ -160,9 +153,9 @@ public Object eval(final HttpServletRequest request,
try (Context context = buildContext()) {

final Object fileName = contextParams.getOrDefault("dot:jsfilename", "sample.js");
final Source userSource = Source.newBuilder(ENGINE_JS, scriptReader, fileName.toString()).build();
final Source userSource = Source.newBuilder(JS_ENGINE, scriptReader, fileName.toString()).build();
final List<Source> dotSources = getDotSources();
final Value bindings = context.getBindings(ENGINE_JS);
final Value bindings = context.getBindings(JS_ENGINE);
contextParams.entrySet().forEach(entry -> bindings.putMember(entry.getKey(), entry.getValue()));
this.addTools(request, response, bindings);

Expand Down Expand Up @@ -220,55 +213,21 @@ private Object asValue (final Value eval, final DotJSON dotJSON) {

private void checkRejected(final Value eval) {

try {
final JSPromiseObject promise = eval.as(JSPromiseObject.class);
if (promise.getPromiseState() == JSPromise.REJECTED) {

final Object[] stackTraceArray = JsDynamicObjectUtils.getObjectArray(promise);
final String strackTrace = stackTraceToString(stackTraceArray);
throw new DotRuntimeException(Map.of(
"message", "Promise rejected",
"rootCause", eval.toString(),
"stackTrace", strackTrace).toString());
}
} catch (ClassCastException e) {

Logger.error(this, e.getMessage());
}
}

private String stackTraceToString (final Object[] stackTraceArray) {

final List<String> stackTraceList = new ArrayList<>();
for (final Object stackTrace: stackTraceArray) {

if (stackTrace instanceof JSErrorObject) {

final GraalJSException graalJSException = JSErrorObject.class.cast(stackTrace).getException();

final List<String> list = Stream.of(graalJSException.getJSStackTrace()).map(this::jsStrackTraceToString).collect(Collectors.toList());
stackTraceList.add(Map.of("message", graalJSException.getMessage(),"jsstackTrace",list).toString());
} else {

stackTraceList.add(stackTrace.toString());
}
StringBuilder sb = new StringBuilder();
for (final Object stackTrace : stackTraceArray) {
sb.append(stackTrace + "\n");
}
return stackTraceList.toString();
}

private String jsStrackTraceToString(final GraalJSException.JSStackTraceElement element) {

return null == element.getClassName()?
"UnknownClass":
element.getClassName() + "." + element.getFunctionName().toString() + getJsStrackTraceFileLineNumber(element);
return sb.toString();
}

private static String getJsStrackTraceFileLineNumber(final GraalJSException.JSStackTraceElement element) {

return "(" + element.getFileName() != null && element.getLineNumber() >= 0 ?
element.getFileName() + ":" + element.getLineNumber() + ")" :
(element.getFileName() != null ? "" + element.getFileName() + ")" : "Unknown Source)");
}


private List<Source> getDotSources() throws IOException {

Expand Down Expand Up @@ -380,7 +339,8 @@ public static Source toSource (final String absolutePath, final File file) {

final StringReader stringReader = new StringReader(sourceContent);
source = Try.of(() ->
Source.newBuilder(ENGINE_JS, stringReader, absolutePath).build()).getOrElseThrow(JsEngineException::new);
Source.newBuilder(JS_ENGINE, stringReader, absolutePath).build())
.getOrElseThrow(JsEngineException::new);
}

return source;
Expand All @@ -401,7 +361,7 @@ public static Source toModuleSource (final String absolutePath, final String mod

final StringReader stringReader = new StringReader(sourceContent);
source = Try.of(() ->
Source.newBuilder(ENGINE_JS, stringReader, modulePath)
Source.newBuilder(JS_ENGINE, stringReader, modulePath)
.mimeType("application/javascript+module")
.build()).getOrElseThrow(JsEngineException::new);
}
Expand All @@ -414,7 +374,8 @@ private Object[] buildArgs(final JsRequest request,
final Object[] objects) {

final Object [] defaultArgsArray = new Object[]{
JsProxyFactory.createProxy(new JsContext.Builder().request(request).response(response).logger(jsDotLogger).build()) };
JsProxyFactory.createProxy(
new Builder().request(request).response(response).logger(jsDotLogger).build())};

return null != objects && objects.length > 0?
CollectionsUtils.concat(defaultArgsArray, objects): defaultArgsArray;
Expand Down

This file was deleted.

4 changes: 4 additions & 0 deletions dotCMS/src/main/resources/container/tomcat9/bin/setenv.sh
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ export CATALINA_OPTS="$CATALINA_OPTS --add-opens java.base/jdk.internal.misc=ALL
export CATALINA_OPTS="$CATALINA_OPTS -Djavax.xml.transform.TransformerFactory=com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"
export CATALINA_OPTS="$CATALINA_OPTS -Djavax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl"
export CATALINA_OPTS="$CATALINA_OPTS -Djavax.xml.parsers.SAXParserFactory=com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+EnableDynamicAgentLoading"




# Set Log4j properties if not already set
if echo "$CATALINA_OPTS" | grep -q '\-Dlog4j2\.configurationFile'; then
Expand Down
Loading
Loading