Install Extensions on demand

We have added the possibility to install the following extension “on demand”:

  • S3 Resource
  • Search (Lucene)
  • ORM (Hibernate)

Means when someone is using for example entityNew(), Lucee automatically installs the Hibernate extension (if possible).

BTW: For new installs and updates from Lucee 4.5 this extension are installed automatically.

So question is what do you think about this “install on demand” feature?

This makes me a uneasy. I’d suggest that the point of code execution is too late to be installing required libraries and that this should be discouraged. If it were implemented with a feature switch, I’d prefer to see the default behaviour have the feature turned off.

Instead, I’d prefer to see published methods for prebuilding Lucee with the dependencies that your application requires. Also, for an error to be thrown when libraries are missing who’s message points at instructions for installing the extension either manually or through some build process.

2 Likes

Same, and for the same reasons. It’s debatable whether this is a feature that should be a run time possibility at all IMO, but it def should not be the default behaviour. And even the usage of it should come with heavy caveats that it’s not the right way to go about things.

1 Like

by default this extensions are bundled with Lucee and installed on a fresh install or an update from 4.5. This is the case for all features that have been moved to an extension and was part of the core in 4.5.

So this functionality only is used when the extension was uninstalled before.

If Lucee fails to install the extension it still throws an exception like this:

return new ApplicationException("No ORM Engine installed!","Check out the Extension Store in the Lucee Administrator for \"ORM\".");

I would prefer if Lucee had an Application ‘package manager’ that had its
dependencies and that would install required extensions

Another option is to use a code analyser that could be run to scan code and
give option to install extensions.

What we kind of have, Lucee 5 defines the “require-extension” in the manifest file of the core, so we can define what extension we like to see installed by default , “require” is maybe the wrong word then you can still uninstall on a later state. We will change that to something like “initial-extension” in the future and as soon we move required stuff to extension we will use again “require-extensions”. (In th future the Lucee core will only be an extension as well, already today there is no big difference between extensions and core)

Analyzing code would be a nice add on but is never a 100% precise on a dynamic language. (Stupid) Example: evaluate(“entity”&“new()”);

entityNew() = that’s super dumb.

  1. plugins should have NO hooks in core whatsoever, it’s ONE optional implementation.

what if I decided to use entityNew() to create a new entity (a person, system or org user) in my system?

or what if I have moved past 2003 and implemented more than just S3 (google drive, Dropbox, etc) with the same hooks?

The whole point of an extension is that it should not have any functionality in the core to use it, so you can roll your own implementation and not have any conflicts.

If I dont’ use ORM, I should be able to use a entity() functions for another purpose.

  1. a great way to exploit the server in realtime… and IMHO introduces an attack surface that shouldn’t be there in the context of running an app.

The problem here is you are assuming entityNew() refers to ORM.

As it is ‘optional’ then one could implement another plugin using entityNew()

Like CFAJAX entityNew() is a pretty bad choice in the first place for a method name for core, but that’s another discussion on drinking and taking drugs before turning up to work at Adobe.

in general you are right, but not in that case then lucee has always an ORM engine running, if no ORM engine is installed, Lucee is using the “DummyORMEngine”, this “ORM Engine” does nothing else than complain that no ORM Engine is installed, so the point is in Lucee the function “entityNew” is hardwired to ORM always, the only thing that can change is the ORM Engine used.

So installing the hibernate extension does not mean that we add the function “entityNew”, it means that we add a different engine behind it. Otherwise this hole ticket would be useless, then without having the extension installed, Lucee would have no clue what “entityNew” is and what it has to do.

The same is the case for S3 and the search.

Is that really a very good approach? What’s the real-world benefit of the hardwiring the functions in the language, but leaving them non-functional?

It’s quite unusual for a module’s API to be present, even when the module itself is not.

I can understand the interface to an ORM system being fixed: defining how the module’s method signatures need to be implemented and the like, but it’s very odd to leave implementation vestiges of it in the language when the implementation is not present.You could (and probably will) argue that there is an implementation present in this “DummyOrmEngine” thing but… why would you do that? Other than to solve the problem you’ve built for yourself by leaving the functions themselves in the language.

How did the decision to do it that way get arrived at? Was this something the TAG decided?

this decision predates Tag, this even predates Lucee itself, this decision was made when we started the Hibernate implementation with Railo (more later).

ORM (not Hibernate) has a very deep integration into the core, as you maybe know you define your ORM objects with components, so a lot of the ORM logic is in the core. Move all this logic to an extension is nearly impossible and would make the code a lot more complicated. In addition it would make no sense as soon you have more than one ORM extension (what is planned) because you would end with a lot of redundant code.

Lucee is aware of ORM, but not of Hibernate, you can compare this with datasources. Lucee is aware of JDBC, but not of MySQL, the complete logic of query objects, the query tags, connection pooling … is in the Lucee core, but everything that is specific to a specific implementation like MySQL is in the JDBC driver itself, that makes the JDBC driver a lot easier to implement. We have exactly the same for ORM as well, all the stuff that is specific for Hibernate is in the extension the rest is in the Lucee core.

This is not new to Lucee 5, we had this separation between hibernate and ORM in general from beginning, then we planned to be open in the future for alternative ORM engines. In fact you can define a different ORM engine in your lucee-server.xml in Lucee 4.5 if you like.

we use the same approach for several functionality:

  • search engine (cfsearch,cfindex,cfcollection …)
  • caches (backend for cfquery cache, resource cache, …, object cache → cachePut,cacheGet …)
  • datasources (cfquery…)
  • virtual file system (all file operations including all file functions and tags)
  • log adapters (cflog)
  • event gateways (SendGatewayMessage)
1 Like

Actually framed like that it makes sense, especially from the perspective of how other stuff in CFML has been implemented, as you point out.

Cool!

@micstriit (or anybody else), could you provide some more information about how exactly ORM gets installed and when? I created a thread here: https://lucee.daemonite.io/t/please-explain-hibernate-orm-installation-initialization-internals/4917