You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ra...@apache.org on 2020/04/17 18:29:15 UTC

[sling-org-apache-sling-scripting-sightly] branch master updated: SLING-9320 - Allow bundled render units to access objects from the same bundle through the Use API

This is an automated email from the ASF dual-hosted git repository.

radu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-sightly.git


The following commit(s) were added to refs/heads/master by this push:
     new bcd4602  SLING-9320 - Allow bundled render units to access objects from the same bundle through the Use API
bcd4602 is described below

commit bcd46027e09182911c55bb244d42debb1bd367c7
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Fri Apr 17 20:26:02 2020 +0200

    SLING-9320 - Allow bundled render units to access objects from the same bundle through the Use API
    
    * merged the code from the SlingModelsUseProvider into the JavaUseProvider, with an
    optional import of the org.apache.sling.models API
    * updated the RenderUnitProvider and ScriptUseProvider to work with bundled
    render units
---
 bnd.bnd                                            |   1 +
 pom.xml                                            |   6 ++
 .../sightly/engine/BundledUnitManager.java         |  57 +++++++++++
 .../scripting/sightly/engine/package-info.java     |   2 +-
 .../sightly/impl/engine/SightlyScriptEngine.java   |   7 +-
 .../impl/engine/SightlyScriptEngineFactory.java    |   4 +-
 ...nitManager.java => BundledUnitManagerImpl.java} | 106 ++++++++++++---------
 .../engine/compiled/SlingHTLMasterCompiler.java    |  24 ++++-
 .../impl/engine/extension/use/JavaUseProvider.java |  40 ++++++--
 .../engine/extension/use/RenderUnitProvider.java   |   4 +-
 .../engine/extension/use/ScriptUseProvider.java    |  66 ++++++++++++-
 11 files changed, 251 insertions(+), 66 deletions(-)

diff --git a/bnd.bnd b/bnd.bnd
index ce8c192..1afbf00 100644
--- a/bnd.bnd
+++ b/bnd.bnd
@@ -12,4 +12,5 @@ Import-Package:     org.apache.sling.scripting.sightly.compiler.*;resolution:=op
                     org.apache.sling.commons.compiler.*;resolution:=optional, \\
                     org.apache.sling.commons.classloader.*;resolution:=optional, \\
                     org.apache.sling.scripting.bundle.tracker.*;resolution:=optional, \\
+                    org.apache.sling.models.*;resolution:=optional, \\
                     *
diff --git a/pom.xml b/pom.xml
index 953bdf3..0d8ede1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -218,6 +218,12 @@
             <version>2.2.8</version>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.models.api</artifactId>
+            <version>1.3.8</version>
+            <scope>provided</scope>
+        </dependency>
 
         <!-- javax.servlet, remove if we do not need a response wrapper -->
         <dependency>
diff --git a/src/main/java/org/apache/sling/scripting/sightly/engine/BundledUnitManager.java b/src/main/java/org/apache/sling/scripting/sightly/engine/BundledUnitManager.java
new file mode 100644
index 0000000..3a04d88
--- /dev/null
+++ b/src/main/java/org/apache/sling/scripting/sightly/engine/BundledUnitManager.java
@@ -0,0 +1,57 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements.  See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership.  The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License.  You may obtain a copy of the License at
+ ~
+ ~   http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied.  See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+package org.apache.sling.scripting.sightly.engine;
+
+import java.net.URL;
+
+import javax.script.Bindings;
+
+import org.apache.sling.scripting.bundle.tracker.BundledRenderUnit;
+import org.apache.sling.scripting.sightly.render.RenderUnit;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.annotation.versioning.ProviderType;
+
+@ProviderType
+public interface BundledUnitManager {
+
+    /**
+     * <p>
+     * Given a {@link Bindings} map, this method will check if the {@code bindings} contain a value for the {@link
+     * BundledRenderUnit#VARIABLE} property and if the object provided by {@link BundledRenderUnit#getUnit()} is an instance of a {@link
+     * RenderUnit}. If so, this service will return the {@link ClassLoader} of the {@link org.osgi.framework.Bundle} providing the {@link
+     * BundledRenderUnit}.</p>
+     *
+     * @param bindings the bindings passed initially to the HTL Script Engine
+     * @return the {@link BundledRenderUnit}'s classloader if one is found, {@code null} otherwise
+     */
+    @Nullable ClassLoader getBundledRenderUnitClassloader(Bindings bindings);
+
+    /**
+     * Given a {@link Bindings} map, this method will check if the {@code bindings} contain a value for the {@link
+     * BundledRenderUnit#VARIABLE} property and, if a {@link BundledRenderUnit} is found, attempt to return the URL of dependency that the
+     * {@link BundledRenderUnit} needs to load. This will take into account the bundle wirings of the unit's providing bundle (see {@link
+     * BundledRenderUnit#getBundle()}).
+     *
+     * @param bindings   the bindings passed initially to the HTL Script Engine
+     * @param identifier the identifier of the dependency that a {@link BundledRenderUnit} from the {@link Bindings} needs to load
+     * @return the URL of the {@code identifier} dependency, if one was found
+     */
+    URL getScript(Bindings bindings, String identifier);
+
+}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/engine/package-info.java b/src/main/java/org/apache/sling/scripting/sightly/engine/package-info.java
index 2b25aa5..88631ad 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/engine/package-info.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/engine/package-info.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  ******************************************************************************/
-@Version("1.0.0")
+@Version("1.1.0")
 package org.apache.sling.scripting.sightly.engine;
 
 import org.osgi.annotation.versioning.Version;
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngine.java b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngine.java
index ef0baf1..e7ceeaf 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngine.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngine.java
@@ -28,7 +28,8 @@ import javax.script.ScriptContext;
 import javax.script.ScriptException;
 
 import org.apache.sling.scripting.api.AbstractSlingScriptEngine;
-import org.apache.sling.scripting.sightly.impl.engine.bundled.BundledUnitManager;
+import org.apache.sling.scripting.sightly.engine.BundledUnitManager;
+import org.apache.sling.scripting.sightly.impl.engine.bundled.BundledUnitManagerImpl;
 import org.apache.sling.scripting.sightly.impl.engine.compiled.SlingHTLMasterCompiler;
 import org.apache.sling.scripting.sightly.render.RenderUnit;
 import org.slf4j.Logger;
@@ -42,11 +43,11 @@ public class SightlyScriptEngine extends AbstractSlingScriptEngine implements Co
     private static final Logger LOGGER = LoggerFactory.getLogger(SightlyScriptEngine.class);
 
     private SlingHTLMasterCompiler slingHTLMasterCompiler;
-    private BundledUnitManager bundledUnitManager;
+    private BundledUnitManagerImpl bundledUnitManager;
     private ExtensionRegistryService extensionRegistryService;
 
     SightlyScriptEngine(SightlyScriptEngineFactory factory, ExtensionRegistryService extensionRegistryService,
-                        SlingHTLMasterCompiler slingHTLMasterCompiler, BundledUnitManager bundledUnitManager) {
+                        SlingHTLMasterCompiler slingHTLMasterCompiler, BundledUnitManagerImpl bundledUnitManager) {
         super(factory);
         this.extensionRegistryService = extensionRegistryService;
         this.slingHTLMasterCompiler = slingHTLMasterCompiler;
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngineFactory.java b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngineFactory.java
index 86ba1dc..93275a1 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngineFactory.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngineFactory.java
@@ -22,7 +22,7 @@ import javax.script.ScriptEngine;
 import javax.script.ScriptEngineFactory;
 
 import org.apache.sling.scripting.api.AbstractScriptEngineFactory;
-import org.apache.sling.scripting.sightly.impl.engine.bundled.BundledUnitManager;
+import org.apache.sling.scripting.sightly.impl.engine.bundled.BundledUnitManagerImpl;
 import org.apache.sling.scripting.sightly.impl.engine.compiled.SlingHTLMasterCompiler;
 import org.osgi.framework.Constants;
 import org.osgi.service.component.annotations.Component;
@@ -49,7 +49,7 @@ public class SightlyScriptEngineFactory extends AbstractScriptEngineFactory {
     private SlingHTLMasterCompiler slingHTLMasterCompiler;
 
     @Reference(cardinality = ReferenceCardinality.OPTIONAL, policyOption = ReferencePolicyOption.GREEDY)
-    private BundledUnitManager bundledUnitManager;
+    private BundledUnitManagerImpl bundledUnitManager;
 
     @Reference
     private ExtensionRegistryService extensionRegistryService;
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/bundled/BundledUnitManager.java b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/bundled/BundledUnitManagerImpl.java
similarity index 76%
rename from src/main/java/org/apache/sling/scripting/sightly/impl/engine/bundled/BundledUnitManager.java
rename to src/main/java/org/apache/sling/scripting/sightly/impl/engine/bundled/BundledUnitManagerImpl.java
index 75732de..f000927 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/bundled/BundledUnitManager.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/bundled/BundledUnitManagerImpl.java
@@ -20,11 +20,11 @@ package org.apache.sling.scripting.sightly.impl.engine.bundled;
 
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.lang.reflect.InvocationTargetException;
 import java.net.URL;
 import java.nio.charset.StandardCharsets;
 
 import javax.script.Bindings;
-import javax.script.CompiledScript;
 import javax.script.ScriptEngineManager;
 import javax.script.ScriptException;
 
@@ -38,6 +38,7 @@ import org.apache.sling.scripting.bundle.tracker.TypeProvider;
 import org.apache.sling.scripting.core.ScriptNameAwareReader;
 import org.apache.sling.scripting.sightly.impl.engine.SightlyCompiledScript;
 import org.apache.sling.scripting.sightly.impl.engine.SightlyScriptEngine;
+import org.apache.sling.scripting.sightly.engine.BundledUnitManager;
 import org.apache.sling.scripting.sightly.impl.utils.BindingsUtils;
 import org.apache.sling.scripting.sightly.render.RenderUnit;
 import org.jetbrains.annotations.NotNull;
@@ -55,7 +56,7 @@ import org.slf4j.LoggerFactory;
 /**
  * The {@code BundledUnitManager} is an optional service, which is made available only if the {@link
  * org.apache.sling.scripting.bundle.tracker} APIs are available. This service allows various components to work with {@link
- * org.apache.sling.scripting.bundle.tracker.BundledRenderUnit} instance and perform dependency resolution based on their availability in
+ * BundledRenderUnit} instance and perform dependency resolution based on their availability in
  * the {@link Bindings} maps passed to the HTL Script Engine.
  */
 @Component(
@@ -64,9 +65,9 @@ import org.slf4j.LoggerFactory;
          * this component will register itself as a service only if the org.apache.sling.scripting.bundle.tracker API is present
          */
         )
-public class BundledUnitManager {
+public class BundledUnitManagerImpl implements BundledUnitManager {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(BundledUnitManager.class);
+    private static final Logger LOGGER = LoggerFactory.getLogger(BundledUnitManagerImpl.class);
 
     private final ServiceRegistration<?> serviceRegistration;
 
@@ -77,7 +78,7 @@ public class BundledUnitManager {
     private ScriptCache scriptCache;
 
     @Activate
-    public BundledUnitManager(BundleContext bundleContext) {
+    public BundledUnitManagerImpl(BundleContext bundleContext) {
         serviceRegistration = register(bundleContext);
     }
 
@@ -129,35 +130,21 @@ public class BundledUnitManager {
         BundledRenderUnit bundledRenderUnit = getBundledRenderUnit(bindings);
         Resource currentResource = BindingsUtils.getResource(bindings);
         if (currentResource != null && bundledRenderUnit != null) {
-            boolean absolute = identifier.charAt(0) == '/';
             for (TypeProvider provider : bundledRenderUnit.getTypeProviders()) {
                 for (ResourceType type : provider.getBundledRenderUnitCapability().getResourceTypes()) {
-                    StringBuilder renderUnitIdentifier = new StringBuilder(identifier);
-                    if (!absolute) {
-                        renderUnitIdentifier = renderUnitIdentifier.insert(0, type.toString() + "/");
+                    String renderUnitIdentifier = getResourceTypeQualifiedPath(identifier, type);
+                    String renderUnitBundledPath = renderUnitIdentifier;
+                    if (renderUnitBundledPath.startsWith("/")) {
+                        renderUnitBundledPath = renderUnitBundledPath.substring(1);
                     }
-                    if (provider.isPrecompiled()) {
-                        String classResourcePath = renderUnitIdentifier.toString();
-                        if (classResourcePath.startsWith("/")) {
-                            classResourcePath = classResourcePath.substring(1);
+                    String className = JavaEscapeHelper.makeJavaPackage(renderUnitBundledPath);
+                    try {
+                        Class<?> clazz = provider.getBundle().loadClass(className);
+                        if (clazz.getSuperclass() == RenderUnit.class) {
+                            return (RenderUnit) clazz.getDeclaredConstructor().newInstance();
                         }
-                        String className = JavaEscapeHelper.makeJavaPackage(classResourcePath);
-                        try {
-                            Class<?> clazz = provider.getBundle().loadClass(className);
-                            if (clazz.getSuperclass() == RenderUnit.class) {
-                                return (RenderUnit) clazz.getDeclaredConstructor().newInstance();
-                            }
-                        } catch (RuntimeException e) {
-                            throw e;
-                        } catch (Exception ignored) {
-                            // do nothing here
-                        }
-                    } else {
-                        String scriptResourcePath = renderUnitIdentifier.toString();
-                        if (scriptResourcePath.startsWith("/")) {
-                            scriptResourcePath = scriptResourcePath.substring(1);
-                        }
-                        URL bundledScriptURL = provider.getBundle().getEntry("javax.script" + "/" + scriptResourcePath);
+                    } catch (ClassNotFoundException e) {
+                        URL bundledScriptURL = provider.getBundle().getEntry("javax.script" + "/" + renderUnitBundledPath);
                         if (bundledScriptURL != null) {
                             try {
                                 SightlyScriptEngine sightlyScriptEngine = (SightlyScriptEngine) scriptEngineManager.getEngineByName(
@@ -167,32 +154,40 @@ public class BundledUnitManager {
                                     if (cachedScript != null) {
                                         return ((SightlyCompiledScript) cachedScript.getCompiledScript()).getRenderUnit();
                                     } else {
-                                        final String finalRenderUnitIdentifier = renderUnitIdentifier.toString();
                                         try (ScriptNameAwareReader reader =
                                                      new ScriptNameAwareReader(new InputStreamReader(bundledScriptURL.openStream(),
-                                                             StandardCharsets.UTF_8),
-                                                             finalRenderUnitIdentifier)) {
+                                                             StandardCharsets.UTF_8), renderUnitIdentifier)) {
                                             SightlyCompiledScript compiledScript =
                                                     (SightlyCompiledScript) sightlyScriptEngine.compile(reader);
-                                            scriptCache.putScript(new CachedScript() {
-                                                @Override
-                                                public String getScriptPath() {
-                                                    return bundledScriptURL.toExternalForm();
-                                                }
-
-                                                @Override
-                                                public CompiledScript getCompiledScript() {
-                                                    return compiledScript;
-                                                }
-                                            });
                                             return compiledScript.getRenderUnit();
                                         }
                                     }
                                 }
-                            } catch (IOException | ScriptException ignored) {
-
+                            } catch (IOException | ScriptException compileException) {
+                                throw new IllegalStateException(compileException);
                             }
                         }
+                    } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
+                        throw new IllegalArgumentException(e);
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    @Override
+    @Nullable
+    public URL getScript(Bindings bindings, String identifier) {
+        BundledRenderUnit bundledRenderUnit = getBundledRenderUnit(bindings);
+        Resource currentResource = BindingsUtils.getResource(bindings);
+        if (currentResource != null && bundledRenderUnit != null) {
+            for (TypeProvider provider : bundledRenderUnit.getTypeProviders()) {
+                for (ResourceType type : provider.getBundledRenderUnitCapability().getResourceTypes()) {
+                    String scriptResourcePath = getResourceTypeQualifiedPath(identifier, type);
+                    URL bundledScriptURL = provider.getBundle().getEntry("javax.script" + "/" + scriptResourcePath);
+                    if (bundledScriptURL != null) {
+                        return bundledScriptURL;
                     }
                 }
             }
@@ -200,6 +195,20 @@ public class BundledUnitManager {
         return null;
     }
 
+    @NotNull
+    private String getResourceTypeQualifiedPath(String identifier, ResourceType type) {
+        boolean absolute = identifier.charAt(0) == '/';
+        StringBuilder renderUnitIdentifier = new StringBuilder(identifier);
+        if (!absolute) {
+            renderUnitIdentifier = renderUnitIdentifier.insert(0, type.toString() + "/");
+        }
+        String scriptResourcePath = renderUnitIdentifier.toString();
+        if (scriptResourcePath.startsWith("/")) {
+            scriptResourcePath = scriptResourcePath.substring(1);
+        }
+        return scriptResourcePath;
+    }
+
     /**
      * <p>
      * Given a {@link Bindings} map, this method will check if the {@code bindings} contain a value for the {@link
@@ -210,6 +219,7 @@ public class BundledUnitManager {
      * @param bindings the bindings passed initially to the HTL Script Engine
      * @return the {@link BundledRenderUnit}'s classloader if one is found, {@code null} otherwise
      */
+    @Override
     @Nullable
     public ClassLoader getBundledRenderUnitClassloader(Bindings bindings) {
         Object bru = bindings.get(BundledRenderUnit.VARIABLE);
@@ -245,7 +255,9 @@ public class BundledUnitManager {
     private ServiceRegistration<?> register(BundleContext bundleContext) {
         try {
             BundledUnitManager.class.getClassLoader().loadClass("org.apache.sling.scripting.bundle.tracker.BundledRenderUnit");
-            return bundleContext.registerService(BundledUnitManager.class, this, null);
+            return bundleContext.registerService(new String[] {BundledUnitManager.class.getName(),
+                            BundledUnitManagerImpl.class.getName()}, this,
+                    null);
         } catch (ClassNotFoundException e) {
             LOGGER.info("No support for bundled RenderUnits.");
         }
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SlingHTLMasterCompiler.java b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SlingHTLMasterCompiler.java
index 14aa3ab..bfa4b3c 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SlingHTLMasterCompiler.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SlingHTLMasterCompiler.java
@@ -33,6 +33,7 @@ import java.util.concurrent.locks.ReentrantLock;
 import java.util.regex.Matcher;
 
 import javax.script.Bindings;
+import javax.script.CompiledScript;
 import javax.script.ScriptContext;
 import javax.script.ScriptEngine;
 import javax.script.ScriptException;
@@ -47,6 +48,8 @@ import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
 import org.apache.sling.commons.compiler.JavaCompiler;
 import org.apache.sling.commons.compiler.Options;
 import org.apache.sling.commons.compiler.source.JavaEscapeHelper;
+import org.apache.sling.scripting.api.CachedScript;
+import org.apache.sling.scripting.api.ScriptCache;
 import org.apache.sling.scripting.api.ScriptNameAware;
 import org.apache.sling.scripting.api.resource.ScriptingResourceResolverProvider;
 import org.apache.sling.scripting.sightly.SightlyException;
@@ -100,6 +103,9 @@ public class SlingHTLMasterCompiler {
     @Reference
     private ResourceBackedPojoChangeMonitor resourceBackedPojoChangeMonitor;
 
+    @Reference
+    private ScriptCache scriptCache;
+
     private static final String NO_SCRIPT = "NO_SCRIPT";
     private static final String JAVA_EXTENSION = ".java";
     static final String SIGHTLY_CONFIG_FILE = "/sightly.config";
@@ -204,6 +210,10 @@ public class SlingHTLMasterCompiler {
                 sName = getScriptName(scriptContext);
             }
             final String scriptName = sName;
+            CachedScript cachedScript = scriptCache.getScript(scriptName);
+            if (cachedScript != null && cachedScript.getCompiledScript() instanceof SightlyCompiledScript) {
+                return (SightlyCompiledScript) cachedScript.getCompiledScript();
+            }
             CompilationUnit compilationUnit = new CompilationUnit() {
                 @Override
                 public String getScriptName() {
@@ -241,7 +251,19 @@ public class SlingHTLMasterCompiler {
             String javaSourceCode = javaClassBackendCompiler.build(sourceIdentifier);
             Object renderUnit = compileSource(sourceIdentifier, javaSourceCode);
             if (renderUnit instanceof RenderUnit) {
-                return new SightlyCompiledScript(engine, (RenderUnit) renderUnit);
+                SightlyCompiledScript compiledScript = new SightlyCompiledScript(engine, (RenderUnit) renderUnit);
+                scriptCache.putScript(new CachedScript() {
+                    @Override
+                    public String getScriptPath() {
+                        return scriptName;
+                    }
+
+                    @Override
+                    public CompiledScript getCompiledScript() {
+                        return compiledScript;
+                    }
+                });
+                return compiledScript;
             } else {
                 throw new SightlyException("Expected a RenderUnit.");
             }
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/JavaUseProvider.java b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/JavaUseProvider.java
index c792921..17e3b12 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/JavaUseProvider.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/JavaUseProvider.java
@@ -30,7 +30,8 @@ import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.adapter.Adaptable;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.scripting.SlingScriptHelper;
-import org.apache.sling.scripting.sightly.impl.engine.bundled.BundledUnitManager;
+import org.apache.sling.models.factory.ModelFactory;
+import org.apache.sling.scripting.sightly.impl.engine.bundled.BundledUnitManagerImpl;
 import org.apache.sling.scripting.sightly.impl.engine.compiled.SlingHTLMasterCompiler;
 import org.apache.sling.scripting.sightly.impl.utils.BindingsUtils;
 import org.apache.sling.scripting.sightly.impl.utils.Patterns;
@@ -77,7 +78,10 @@ public class JavaUseProvider implements UseProvider {
     private SlingHTLMasterCompiler slingHTLMasterCompiler;
 
     @Reference(cardinality = ReferenceCardinality.OPTIONAL, policyOption = ReferencePolicyOption.GREEDY)
-    private BundledUnitManager bundledUnitManager;
+    private BundledUnitManagerImpl bundledUnitManager;
+
+    @Reference(cardinality = ReferenceCardinality.OPTIONAL, policyOption = ReferencePolicyOption.GREEDY)
+    private ModelFactory modelFactory;
 
     @Override
     public ProviderOutcome provide(String identifier, RenderContext renderContext, Bindings arguments) {
@@ -149,11 +153,12 @@ public class JavaUseProvider implements UseProvider {
                                        @NotNull Bindings arguments)
             throws NoSuchMethodException, IllegalAccessException, InvocationTargetException,
             InstantiationException {
-            // attempt OSGi service load
+            // OSGi service
             Object result = serviceLoader.getService(cls);
             if (result != null) {
                 return ProviderOutcome.success(result);
             }
+            // adaptable
             Object adaptableCandidate = arguments.get(ADAPTABLE);
             if (adaptableCandidate instanceof Adaptable) {
                 Adaptable adaptable = (Adaptable) adaptableCandidate;
@@ -163,20 +168,37 @@ public class JavaUseProvider implements UseProvider {
                 }
             }
             SlingHttpServletRequest request = BindingsUtils.getRequest(globalBindings);
+            Resource resource = BindingsUtils.getResource(globalBindings);
+            // Sling Model
+            if (modelFactory != null && modelFactory.isModelClass(cls)) {
+                try {
+                    // try to instantiate class via Sling Models (first via request, then via resource)
+                    if (request != null && modelFactory.canCreateFromAdaptable(request, cls)) {
+                        LOG.debug("Trying to instantiate class {} as Sling Model from request.", cls);
+                        return ProviderOutcome.notNullOrFailure(modelFactory.createModel(request, cls));
+                    }
+                    if (resource != null && modelFactory.canCreateFromAdaptable(resource, cls)) {
+                        LOG.debug("Trying to instantiate class {} as Sling Model from resource.", cls);
+                        return ProviderOutcome.notNullOrFailure(modelFactory.createModel(resource, cls));
+                    }
+                    return ProviderOutcome.failure(
+                            new IllegalStateException("Could not adapt the given Sling Model from neither request nor resource: " + cls));
+                } catch (Exception e) {
+                    return ProviderOutcome.failure(e);
+                }
+            }
             if (request != null) {
                 result = request.adaptTo(cls);
             }
-            if (result == null) {
-                Resource resource = BindingsUtils.getResource(globalBindings);
-                if (resource != null) {
-                    result = resource.adaptTo(cls);
-                }
+            if (result == null && resource != null) {
+                result = resource.adaptTo(cls);
             }
             if (result != null) {
                 return ProviderOutcome.success(result);
             } else if (cls.isInterface() || Modifier.isAbstract(cls.getModifiers())) {
                 LOG.debug("Won't attempt to instantiate an interface or abstract class {}", cls.getName());
-                return ProviderOutcome.failure();
+                return ProviderOutcome.failure(new IllegalArgumentException(String.format(" %s represents an interface or an abstract " +
+                        "class which cannot be instantiated.", cls.getName())));
             } else {
                 /*
                  * the object was cached by the class loader but it's not adaptable from {@link Resource} or {@link
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java
index 4e51995..d3398d1 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java
@@ -39,7 +39,7 @@ import org.apache.sling.scripting.sightly.engine.ResourceResolution;
 import org.apache.sling.scripting.sightly.impl.engine.SightlyCompiledScript;
 import org.apache.sling.scripting.sightly.impl.engine.SightlyScriptEngine;
 import org.apache.sling.scripting.sightly.impl.engine.SightlyScriptEngineFactory;
-import org.apache.sling.scripting.sightly.impl.engine.bundled.BundledUnitManager;
+import org.apache.sling.scripting.sightly.impl.engine.bundled.BundledUnitManagerImpl;
 import org.apache.sling.scripting.sightly.impl.utils.BindingsUtils;
 import org.apache.sling.scripting.sightly.impl.utils.ScriptUtils;
 import org.apache.sling.scripting.sightly.render.RenderContext;
@@ -77,7 +77,7 @@ public class RenderUnitProvider implements UseProvider {
     private ScriptCache scriptCache;
 
     @Reference
-    private BundledUnitManager bundledUnitManager;
+    private BundledUnitManagerImpl bundledUnitManager;
 
     @Reference
     private ScriptEngineManager scriptEngineManager;
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java
index 10305f0..c525f6b 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java
@@ -19,14 +19,32 @@
 
 package org.apache.sling.scripting.sightly.impl.engine.extension.use;
 
+import java.io.IOException;
+import java.io.StringReader;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+
 import javax.script.Bindings;
+import javax.script.Compilable;
+import javax.script.CompiledScript;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import javax.script.SimpleBindings;
+import javax.script.SimpleScriptContext;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.scripting.SlingBindings;
 import org.apache.sling.api.scripting.SlingScript;
+import org.apache.sling.scripting.api.CachedScript;
+import org.apache.sling.scripting.api.ScriptCache;
 import org.apache.sling.scripting.api.resource.ScriptingResourceResolverProvider;
+import org.apache.sling.scripting.core.ScriptNameAwareReader;
 import org.apache.sling.scripting.sightly.impl.engine.SightlyScriptEngineFactory;
+import org.apache.sling.scripting.sightly.impl.engine.bundled.BundledUnitManagerImpl;
 import org.apache.sling.scripting.sightly.impl.utils.BindingsUtils;
 import org.apache.sling.scripting.sightly.impl.utils.ScriptUtils;
 import org.apache.sling.scripting.sightly.render.RenderContext;
@@ -35,6 +53,8 @@ import org.apache.sling.scripting.sightly.use.UseProvider;
 import org.osgi.framework.Constants;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
 import org.osgi.service.metatype.annotations.AttributeDefinition;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -42,7 +62,7 @@ import org.slf4j.LoggerFactory;
 /**
  * Use provider that interprets the identifier as a script path, and runs the respective script using a script engine that matches the
  * script extension.
- *
+ * <p>
  * This provider returns a non-failure outcome only if the evaluated script actually returns something. For more details check the
  * implementation of the {@link SlingScript#eval(SlingBindings)} method for the available script engines from your platform.
  */
@@ -71,6 +91,15 @@ public class ScriptUseProvider implements UseProvider {
     @Reference
     private ScriptingResourceResolverProvider scriptingResourceResolverProvider;
 
+    @Reference(cardinality = ReferenceCardinality.OPTIONAL, policyOption = ReferencePolicyOption.GREEDY)
+    private BundledUnitManagerImpl bundledUnitManager;
+
+    @Reference
+    private ScriptEngineManager scriptEngineManager;
+
+    @Reference
+    private ScriptCache scriptCache;
+
     @Override
     public ProviderOutcome provide(String scriptName, RenderContext renderContext, Bindings arguments) {
         Bindings globalBindings = renderContext.getBindings();
@@ -79,6 +108,41 @@ public class ScriptUseProvider implements UseProvider {
         if (extension == null || extension.equals(SightlyScriptEngineFactory.EXTENSION)) {
             return ProviderOutcome.failure();
         }
+        if (bundledUnitManager != null) {
+            URL script = bundledUnitManager.getScript(bindings, scriptName);
+            if (script != null) {
+                String scriptUrlAsString = script.toExternalForm();
+                bindings.remove("org.apache.sling.scripting.bundle.tracker.BundledRenderUnit");
+                bindings.put(ScriptEngine.FILENAME, scriptUrlAsString);
+                try {
+                    ScriptEngine scriptEngine = scriptEngineManager.getEngineByExtension(extension);
+                    if (scriptEngine != null) {
+                        if (scriptEngine instanceof Compilable) {
+                            CompiledScript compiledScript;
+                            CachedScript cachedScript = scriptCache.getScript(scriptUrlAsString);
+                            if (cachedScript == null) {
+                                Compilable compilableScriptEngine = (Compilable) scriptEngine;
+                                ScriptNameAwareReader reader =
+                                        new ScriptNameAwareReader(new StringReader(IOUtils.toString(script, StandardCharsets.UTF_8)),
+                                                scriptUrlAsString);
+                                compiledScript = compilableScriptEngine.compile(reader);
+                            } else {
+                                compiledScript = cachedScript.getCompiledScript();
+                            }
+                            return ProviderOutcome.notNullOrFailure(compiledScript.eval(bindings));
+                        } else {
+                            ScriptNameAwareReader reader =
+                                    new ScriptNameAwareReader(new StringReader(IOUtils.toString(script, StandardCharsets.UTF_8)),
+                                            scriptUrlAsString);
+                            return ProviderOutcome
+                                    .notNullOrFailure(scriptEngine.eval(reader, bindings));
+                        }
+                    }
+                } catch (Exception e) {
+                    return ProviderOutcome.failure(e);
+                }
+            }
+        }
         Resource scriptResource = ScriptUtils.resolveScript(scriptingResourceResolverProvider.getRequestScopedResourceResolver(),
                 renderContext, scriptName);
         if (scriptResource == null) {