PhoenicisOrg / phoenicis

Phoenicis PlayOnLinux and PlayOnMac 5 repository
https://phoenicis.org/
GNU Lesser General Public License v3.0
683 stars 73 forks source link

Make the script agnostic of the platform #1630

Open qparis opened 5 years ago

qparis commented 5 years ago

Currently, our script base depends on the platform Phoenicis and, specifically on Java. I suggest we add an extra abstraction layer, so that side projects can use our scripts if they want.

madoar commented 5 years ago

Hmm, this sounds like a useful idea. The problem is how can we achieve it? I mean currently both the input and the output of the scripts are depending on the Java backend. For example, for the input we provide some Java bean objects which are used heavily. For the output we want to return Java objects, which we can use/access in a safe manner from inside Phoenicis. Even internally in the scripts Java is used. For example the whole file access is implemented via the Java File objects.

qparis commented 5 years ago

For example, for the input we provide some Java bean objects which are used heavily.

We can decide that we have to use Bean() to load any Java object. Then, we can documente the interface the bean should have and it will be good enough

For the output we want to return Java objects, which we can use/access in a safe manner from inside Phoenicis.

Same, as long as the interfaces can be implemented, we are good.

Even internally in the scripts Java is used. For example the whole file access is implemented via the Java File objects.

I think we need to create a generic File object that encapsulate the Java one

madoar commented 5 years ago

I don't think this can be achieved by defining an interface. A lot of our script code depends on nashorn specific methods to allow for an easy interoperability with Java. This means that the scripts can only be executed with nashorn.

This in turn leads to another problem in the not to near future, because nashorn has been deprecated with JDK 11. We are still searching for an alternative, see also #1352.

qparis commented 5 years ago

I don't think this can be achieved by defining an interface. A lot of our script code depends on nashorn specific methods to allow for an easy interoperability with Java. This means that the scripts can only be executed with nashorn.

This is what we need to work on. Can we enumerate what Nashorn specific features we need?

madoar commented 5 years ago

I can think of the following Nashorn specific features currently:

Maybe @plata knows some more.

qparis commented 5 years ago

I can think of the following Nashorn specific features currently:

* access control to Java classes

Do we still need this if we always use bean()?

madoar commented 5 years ago

I don't know, but can we use bean() for everything? Currently we instantiate a lot of Java classes. A benefit of Nashorn is, that we can use our custom @Safe annotation to mark all Java classes we want to allow access to from inside JavaScript.

After thinking about it some more I believe it is also a good idea to extend the access control further. For example we should also limit the access of the scripts on the filesystem only to specific folders. I don't believe the scripts should be able to modify host system relevant files and folders.

It would be nice if a new solution would support this.

plata commented 5 years ago

I don't know which Nashorn specific features we're using. My plan was to figure that out by trial and error when replacing Nashorn ;).

Regarding the beans: Can I call a script from lets say C++ and still have this mechanism?

qparis commented 5 years ago

In thoery yes, because Bean() is just a factory. It returns an object, you can do whatever you want with it

plata commented 5 years ago

I see. Still do not understand how scripts can implement an OOP API with this requirement.

qparis commented 5 years ago

What problem would you see?

plata commented 5 years ago

I just can imagine how it is done (technically). Currently, we have Java.extend. How exactly will this be replaced?

plata commented 5 years ago

Just found an interesting article about implement-js: https://hackernoon.com/implementing-interfaces-in-javascript-with-implement-js-8746838f8caa

madoar commented 5 years ago

@plata I prefer typescript. The issue with typescript is, that Nashorn doesn't support it, but graaljs does (I think).

plata commented 5 years ago

Actually, I was thinking about typescript as well but I think it has some disadvantages:

qparis commented 5 years ago

I just can imagine how it is done (technically). Currently, we have Java.extend. How exactly will this be replaced?

In fact, when you use Java.extend, I think that it allows you multiple things and we should be clear about what we really need.

Don't know if I'm clear

plata commented 5 years ago

Actually, the OOP API has to purposes:

If the scripts shall be platform agnostic, the logical consequence for me would be to create a separate repository defining the API (in JS). For this purpose, implement-js could be helpful. Of course it is always possible to call any JS function from the embedding software but I really would like to be more explicit about the interfaces.

qparis commented 5 years ago

Of course it is always possible to call any JS function from the embedding software but I really would like to be more explicit about the interfaces.

I think that the interface we need to respect is more a concept than anything else. The way there are formalized is not very important and does not put into question this issue: it can be a Java interface (which is a good choice IMHO). We can later formalize them in JSON and autogenerate Java Interface or whatever

madoar commented 5 years ago

@plata typescript is mainly javascript with types, I don't think it is an issue for many people. Typescript is transpiled into javascript, we could either have the users do this before a PR is merged or by Phoenicis when a repository containing typescript files has been downloaded. Typescript seems to be usable with graaljs, they have some examples using typescript (see here).

@qparis you're right, we mainly need Java.extend to access JS objects from Java. How would the BeanRegister method be implemented and then used?

qparis commented 5 years ago

@qparis you're right, we mainly need Java.extend to access JS objects from Java. How would the BeanRegister method be implemented and then used?

Three things to take into consideration:

BeanRegister(jsObject) would work like this:

madoar commented 5 years ago

Why could FooProxy be replaced by a generic class? I mean we have 4 or 5 different interfaces each for a different script type (installation script, verb, tool, etc.) and each with its own custom set of methods. How does a generic class help here?

plata commented 5 years ago

Regarding typescript. @madoar I'm not sure but this is not the engine which is available in OpenJDK is it?

@qparis yes, it's a concept. Nevertheless, I think we should have it in JS. Imagine someone wants to use it in C++: It makes sense that she can just use any JS engine and is ready to go. If we define the interface in JSON, it requires additional domain specific work/knowledge to use this.

qparis commented 5 years ago

@qparis yes, it's a concept. Nevertheless, I think we should have it in JS. Imagine someone wants to use it in C++: It makes sense that she can just use any JS engine and is ready to go. If we define the interface in JSON, it requires additional domain specific work/knowledge to use this.

I understand, but I think it can be done on a next step. The very first important step is to be clear on what interface clients should support

Why could FooProxy be replaced by a generic class? I mean we have 4 or 5 different interfaces each for a different script type (installation script, verb, tool, etc.) and each with its own custom set of methods. How does a generic class help here?

The generic proxy could automatically bind its own method to its delegate. Not sure how important it is regarding the number of different interfaces we have though.

plata commented 5 years ago

Ok. I just wanted to get a wholistic picture of the thing. I think our next step must be GraalVM.

qparis commented 5 years ago

Yes. It might also solve memory issues. Does graalVM replace OpenJDK by the way?

madoar commented 5 years ago

@plata I don't understand why our next step must be GraalVM?

About typescript: The current OpenJDK includes Nashorn, which doesn't support typescript. Graaljs is the Javascript implementation of GraalVM, which does support typescript but is still under heavy development.

As far as I know Graaljs doen't require GraalVM to run it also works with a "normal" JRE/JDK. Graaljs makes an exception in this regard, because the other language implementations of GraalVM (Python, R, etc.) will only run on GraalVM.

qparis commented 5 years ago

How does GraalVM works? Is it a replacement for JDK?

madoar commented 5 years ago

I'm not sure. I only know that starting with JDK 10 the graal compiler has been added to OpenJDK, see here. Whether GraalVM will replace the JRE/JDK in the future or not I'm not sure.

An interesting feature of GraalVM is, that it allows for the compilation into native executables. This suggests that it can at least be used as an alternative to the classic JRE/JDK.

qparis commented 5 years ago

Can we make a quick test? Also, I'd like to see how it behaves with #1425

madoar commented 5 years ago

What do you want to test? GraalVM or Graaljs?

I don't think that we can get it working quickly. GraalVM doesn't provide Nashorn as far as I know. It provides Graaljs by default. Graaljs in turn has some differences to Nashorn which requires some changes to our code base. Graaljs can also be included via maven, but I don't know how well the integration via maven works currently, because officially this is not supported yet.

plata commented 5 years ago

From the GraalVM docs:

GraalVM is a standalone Java Development Kit that you can use for executing Java or JVM-based applications

qparis commented 5 years ago

Currently, I could not make GraalVM work with JavaFX. (GraalVM seems to be based on Java 1.8 which does not work with OpenJFX). Also, GraalVM is not included in mains distro repos

plata commented 5 years ago

Lets discuss the GraalVM related stuff in #1352.