Skip to content
This repository has been archived by the owner on Sep 28, 2022. It is now read-only.

FIX 496 : Add support for CodeSource URL for GoloClassLoader #497

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ private Class<?> loadGoloFile(String goloFile, String module, GoloClassLoader lo
}
} else if (file.getName().endsWith(".golo")) {
try (FileInputStream in = new FileInputStream(file)) {
Class<?> loadedClass = loader.load(file.getName(), in);
Class<?> loadedClass = loader.load(file.getName(), in, file.toURI().toURL());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Build the CodeSource instance here (see the proposed load refactoring). This will allows to construct a Certificate[] from command line options if we ever need to.
BTW, the file scanning facility should be extracted.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yloiseau what do you mean by "extracted"?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be a mode generic method that scan (recursively) a directory and return golo files, maybe in the form of a CodeSource object, or Path with a method to convert a Path into a CodeSource

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see the "extract method" refactoring...

if (module == null || loadedClass.getCanonicalName().equals(module)) {
return loadedClass;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ private Class<?> loadGoloFile(GoloClassLoader loader, Path path) {
try (InputStream is = Files.newInputStream(path)) {
Path filename = path.getFileName();
if (filename != null) {
return loader.load(filename.toString(), is);
return loader.load(filename.toString(), is, path.toUri().toURL());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idem

} else {
throw new RuntimeException(message("not_regular_file", path));
}
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/org/eclipse/golo/compiler/GoloClassLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
package org.eclipse.golo.compiler;

import java.io.InputStream;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.util.List;

/**
Expand Down Expand Up @@ -58,4 +62,25 @@ public synchronized Class<?> load(String goloSourceFilename, InputStream sourceC
}
return lastClassIsModule;
}

/**
* Compiles and loads the resulting JVM bytecode for a Golo source file.
* This method declares a URL for the CodeSource of this class, which
* is useful for retrieving the location at runtime.
*
* @param goloSourceFilename the source file name.
* @param sourceCodeInputStream the source input stream.
* @param sourceCodeLocation the source file location.
* @return the class matching the Golo module defined in the source.
* @throws GoloCompilationException if either of the compilation phase failed.
*/
public synchronized Class<?> load(String goloSourceFilename, InputStream sourceCodeInputStream, URL sourceCodeLocation) throws GoloCompilationException {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is copy/past from the previous one. You should refactor the previous one to call this one with a null location.
Or even better, as stated in the main comments, refactor the method to only take a CodeSource and derive the name and input stream from it, and remove the old one.

List<CodeGenerationResult> results = compiler.compile(goloSourceFilename, sourceCodeInputStream);
Class<?> lastClassIsModule = null;
for (CodeGenerationResult result : results) {
byte[] bytecode = result.getBytecode();
lastClassIsModule = defineClass(null, bytecode, 0, bytecode.length, new ProtectionDomain(new CodeSource(sourceCodeLocation, (Certificate[])null), null));
}
return lastClassIsModule;
}
}