[rebase of #2206] SI-874 JSR-223 compliance for the interpreter#2238
[rebase of #2206] SI-874 JSR-223 compliance for the interpreter#2238adriaanm merged 2 commits intoscala:masterfrom
Conversation
|
LGTM |
|
The modularisation isn't done yet. We won't stop until these things are in separate github projects, with their own artifacts. We want to be able to accept and publish improvements to them independently of the compiler's schedule. |
[rebase of #2206] l JSR-223 compliance for the interpreter
There was a problem hiding this comment.
It's my bad for letting adriaan handle these delicate matters and not managing any review myself, but there is a lot wrong with this method, among which is that it breaks running against anything which isn't a jar because regular paths don't have a ! in them.
|
Here is the code to invoke scala-2.11.0-M2 interpreter through JSR223. Writing the code, I found two problems.
Former problem is more serious when the Scala interpreter invoked in webapp. |
|
Thanks to all who worked on building support for JSR-233 scala scripting!
|
|
Cool! Thanks for letting us know (and for sharing workarounds!). Always nice to hear about successes -- makes for a nice change from bug reports :-) |
|
It will be nice if any news in the progress making Scala integrate with JSR-223 going to the scala-lang.org asap! Thanks and keep rocking! |
Finished implementations for various classpath types - also using ManifestResources. In accordance with the idea and the initial implementation of @gkossakowski they tries to make the best use of the specificity of a given file type instead of using AbstractFile everywhere. From now flat classpath really works and can be turned on. There are following types of flat classpath: for both source and class files: - for directories - it uses the real directory having representation on a disk - for zip and jar files - it uses FileZipArchive - Grzegorz was doing some experiments with different ways of handling such files (efficiency etc.) and stated that this one is the best. - aggregate - equivalent of MergedClassPath from the old implementation. It groups classpath instances created for different files. It ensures the distinction of cp entries and merges corresponding entries for class and source files into one entry as SymbolLoaders class makes use of that. only for class files: - for ManifestResources - it's closely related to the support for JSR-223 and to classes listed in the jar's manifest. In general right now it's not possible to use it in Scala out of the box (without using additional tools) as this support is postponed. The old classpath has been properly prepared in the PR created by @rjolly scala#2238 so the new one also got this feature. ManifestResources is a ZipArchive without a real underlying file placed on a disk and in addition with some unsupported methods from AbstractFile so the implementation has to use the iterator provided by AbstractFile. There's added caching for classpath for zip and jar files and for ManifestResources which can be turned off using a flag -YdisableFlatCpCaching. The cache is just a map AbstractFile -> FlatClassPath what should reduce the number of created cp and file instances e.g. in the case of many ScalaPresentationCompilers in Scala IDE. There's no added cache for loaded symbols etc. (honestly I didn't look at that - I'm even not sure how much sense would have such things). In SymbolLoaders there's added PackageLoaderUsingFlatClassPath that was needed as the new implementation uses relatively few cp objects which can return entries from many packages. In the case of old implementation there's the structure of nested classpath objects, where each such an object can return only entries from one level of hierarchy but it returns also another classpath objects for nested levels included in it. I removed sbt compiler interface hack - instead of it there's introduced the dynamic dispatch in Global's classPath method. The type of classPath changed from ClassPath[AbstractFile] to ClassFileLookup[AbstractFile] but it should be okay as ClassFileLookup defines needed methods. I tested it with sbt and everything seemed to work correctly. But it could be problematic if someone uses classPath from Global and requires exactly the old implementation. I'm not aware of such cases. In the case of compatibility problems with some libraries using compiler's internals we could think about bringing back some hacks. But it would be better to avoid this. I created PathResolverFactory which is used instead of a concrete implementation of PathResolver - it dispatches to the proper classpath implementation so, in combination with matches in some other places, all places using classpath create/get the proper type of it. I changed scalap's Main.scala to be able to use both implementations and also to use flags related to the classpath implementation. By the way the structure of its methods has been refactored - there's no change in a way in which scalap works. The classpath invalidation is modified to work properly for the old cp implementation after changes made in Global. In the case of the attempt to use the invalidation for the flat cp right now it just throws exception with a message that the flat one currently doesn't support the invalidation. And also that's why the partest's test for the invalidation has been changed to use (always) the old implementation. There's added proper comment with TODO to this file. As I always do - I removed unused private methods, unused imports and commented lines which I saw by the way and were obvious for me. In the case of less obvious commented lines I added TODOs as someone should look at such places some day and clean them up.
Finished implementations for various classpath types - also using ManifestResources. In accordance with the idea and the initial implementation of @gkossakowski they try to make the best use of the specificity of a given file type instead of using AbstractFile everywhere. From now flat classpath really works and can be turned on. There are following types of flat classpath: for both source and class files: - for directories - it uses the real directory having representation on a disk - for zip and jar files - it uses FileZipArchive - Grzegorz was doing some experiments with different ways of handling such files (efficiency etc.) and stated that this one is the best. - aggregate - equivalent of MergedClassPath from the old implementation. It groups classpath instances created for different files. It ensures the distinction of cp entries and merges corresponding entries for class and source files into one entry as SymbolLoaders class makes use of that. only for class files: - for ManifestResources - it's closely related to the support for JSR-223 and to classes listed in the manifest file placed in the JAR. In general right now it's not possible to use it in Scala out of the box (without using additional tools such as jarlister) as this support is postponed. The old classpath has been properly prepared in the PR created by @rjolly scala#2238 so the new one also got this feature. ManifestResources is a ZipArchive without a real underlying file placed on a disk and in addition implementing some methods declared in AbstractFile as unsupported operations. Therefore the implementation has to use the iterator provided by AbstractFile. There's added caching for classpath for zip and jar files and also for ManifestResources. It can be turned off using a flag -YdisableFlatCpCaching. The cache is just a map AbstractFile -> FlatClassPath what should reduce the number of created cp and file instances e.g. in the case of many ScalaPresentationCompilers in Scala IDE. There's no added cache for loaded symbols etc. (honestly I didn't look at that - I'm even not sure how much sense would have such things). In SymbolLoaders there's added PackageLoaderUsingFlatClassPath that was needed as the new implementation uses relatively few cp objects which can return entries from many packages. In the case of old implementation there's the structure of nested classpath objects, where each such an object can return only entries from one level of hierarchy but it returns also another classpath objects for nested levels included in it. The sbt compiler interface hack is removed - instead of it there's introduced the dynamic dispatch in a Global's classPath method. The type of a classPath is changed from ClassPath[AbstractFile] to ClassFileLookup[AbstractFile] but it should be okay as ClassFileLookup defines needed methods. I tested it with sbt and everything seemed to work correctly. But it could be problematic if someone uses a classPath from a Global and requires exactly the type of the old implementation. I'm not aware of such cases. In the case of compatibility problems with some libraries using compiler's internals we could think about bringing back some hacks. But it would be better to avoid this. There's added PathResolverFactory which is used instead of a concrete implementation of a PathResolver - it dispatches to the proper classpath implementation so, in combination with matches in some other places, in all places using classpath we create/get the proper type. Scalap's Main.scala is changed to be able to use both implementations and also to use flags related to the classpath implementation. By the way the structure of its methods has been refactored - there's no change in a way scalap works. The classpath invalidation is modified to work properly for the old cp implementation after changes made in a Global. In the case of the attempt to use the invalidation for the flat cp it just throws exception with a message that the flat one currently doesn't support the invalidation. And also that's why the partest's test for the invalidation has been changed to use (always) the old implementation. There's added an adequate comment with TODO to this file. As I always do - I removed unused private methods, unused imports and commented out lines which I saw by the way and were obvious for me. In the case of less obvious commented out lines I added TODOs as someone should look at such places some day and clean them up.
There's added the flat classpath type using ManifestResources, closely related to the support for JSR-223 (Scripting for the Java Platform). It uses classes listed in the manifest file placed in the JAR. It's related to jar files so it's created using ZipAndJarFlatClassPathFactory and is cached. In general currently it's not possible to use it in Scala out of the box (without using additional tools such as jarlister) as this support is postponed. The old classpath has been properly prepared in the PR created by @rjolly scala#2238 so the new one also got this feature. ManifestResources is a ZipArchive without a real underlying file placed on a disk and in addition implementing some methods declared in AbstractFile as unsupported operations. Therefore the implementation has to use the iterator. I wanted to have the similar behaviour as in the case of directories and zip/jar files - be able to get a directory entry for a package without iterating all entries. This is achieved by iterating all entries only once and caching packages. This flat classpath type was the last needed one.
|
Anyone can give us an example how to use scripting in scala standard app not in REPL? |
|
@duffqiu does the @takawitter gist above not fit your need ? |
|
No. It misses something I figure out now. if we miss The optional ways is to use the -Xbootclasspath/a:/<xxx.jar> way to include all the scala jar files when call |
|
Yes, it's in @takawitter 's gist. Note that, as I said in the gist comments, this is not the right way to do it, which is to "jarlist" scala-library.jar . I am going to write a FAQ. |
|
please do that. If you could push the scala-lang is more better as the tutorial BTW, jarlist is a standard tool? |
|
Hi. No, jarlister is not the standard Scala tool. You can get it from rjolly's repository (https://github.com/rjolly/jarlister) and then use it to modify your jar files. @rjolly will provide more details, I think. |
|
I think scala office needs to provide a standard way how to use scala as script. I saw @rjolly 's jarlister, but it is 2 years ago. So I am afraid to use it. -:) |
|
Hi @takawitter, Any update on the FAQ? |
|
@duffqiu I have updated the scala version in the jarlister build file. |
|
@duffqiu I don't figure out what's the problem.
|
|
I found that usemanifestcp is valid only for jars (invalid for directories in classpath) because of |
|
Yes it is on purpose. Manifest is only meaningful for jars. Hence classes in directories cannot be made available through this mechanism. I don't know what it would imply to implement it, but I don't think it is indispensable (one can always make a jar file). For further info regarding this and other questions see http://jscl-meditor.sourceforge.net/scalaint.pdf http://jscl-meditor.sourceforge.net/scalaint-slides.pdf |
To take full advantage of JSR-223 compatibility, added in 2.11, one must list a jar's classes into its manifest, to make the library visible from the interpreter when run with jrunscript. This is necessary for scala-library.jar, but also any third party library. This commit provides a jarlister utility, together with ant task and documentation. I made an independent jarlister project available on github, but users are afraid of using it, as it is not official, see the comments in scala#2238
To take full advantage of JSR-223 compatibility, added in 2.11, one must list a jar's classes into its manifest, to make the library visible from the interpreter when run with jrunscript. This is necessary for scala-library.jar, but also any third party library. This commit provides a jarlister utility, together with ant task and documentation. I made an independent jarlister project available on github, but users are afraid of using it, as it is not official, see the comments in scala#2238
To take full advantage of JSR-223 compatibility, added in 2.11, one must list a jar's classes into its manifest, to make the library visible from the interpreter when run with jrunscript. This is necessary for scala-library.jar, but also any third party library. This commit provides a jarlister utility, together with ant task and documentation. I made an independent jarlister project available on github, but users are afraid of using it, as it is not official, see the comments in scala#2238
|
I’m not sure what you mean. It would be great if you could file a bug report that explains exactly what is broken. |
review by @rjolly to make sure I didn't butcher anything during the rebase