-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace direct usage of ClassLoader with ResourcesLoader #2059
Conversation
…or deprecate direct usage of class loaders from the engine
jme3-core/src/main/java/com/jme3/util/res/ResourcesLoaderImpl.java
Outdated
Show resolved
Hide resolved
Do you have an implementation of ResourceLoader that is compatible with Teavm? |
Yes, the resource loader for teavm loads from the site root package com.jme3.web.filesystem;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.teavm.jso.browser.Window;
import com.jme3.util.res.ResourcesLoaderImpl;
public class WebResourceLoaderImpl implements ResourcesLoaderImpl {
private static final Logger logger = Logger.getLogger(WebResourceLoaderImpl.class.getName());
private String getFullPath(Class<?> clazz, String path) {
String resourcePath = path;
if (clazz != null) {
String className = clazz.getName();
String classPath = className.replace('.', '/') + ".class";
classPath = classPath.substring(0, classPath.lastIndexOf('/'));
resourcePath = classPath + "/" + path;
}
try {
URL baseURL = new URL(Window.current().getLocation().getFullURL());
resourcePath = new URL(baseURL, resourcePath).toString();
} catch (MalformedURLException e) {
e.printStackTrace();
}
return resourcePath;
}
@Override
public URL getResource(String path, Class<?> clazz) {
path = getFullPath(clazz, path);
logger.log(Level.FINE, "Fetch resource {0}", path);
try {
URL url = new URL(path);
return url;
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
@Override
public InputStream getResourceAsStream(String path, Class<?> clazz) {
path = getFullPath(clazz, path);
logger.log(Level.FINE, "Fetch resource as stream {0}", path);
try {
URL url = new URL(path);
InputStream is = url.openStream();
return is;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
public Enumeration<URL> getResources(String path, Class<?> clazz) throws IOException {
List<URL> urls = new ArrayList<URL>();
try {
String indexPath = "/index.dat";
logger.log(Level.FINE, "Fetch resources index {0}", indexPath);
URL resourcesIndex = getResource(indexPath, null);
ByteArrayOutputStream resourcesBo = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int read = 0;
InputStream is = resourcesIndex.openStream();
while ((read = is.read(buffer)) > 0) {
resourcesBo.write(buffer, 0, read);
}
is.close();
logger.log(Level.FINE, "Listing resources in {0}", path);
String resources[] = new String(resourcesBo.toByteArray(), Charset.forName("UTF-8")).split("\n");
for (String resource : resources) {
resource = resource.trim();
if (resource.length() > 0 && resource.startsWith(path)) {
URL url = getResource(resource, null);
urls.add(url);
}
}
logger.log(Level.FINE, "Found {0} resources in {1}", new Object[] { urls.size(), path });
} catch (Exception e) {
e.printStackTrace();
}
return Collections.enumeration(urls);
}
} |
jme3-core/src/main/java/com/jme3/util/res/DefaultResourceLoader.java
Outdated
Show resolved
Hide resolved
jme3-core/src/plugins/java/com/jme3/asset/plugins/ClasspathLocator.java
Outdated
Show resolved
Hide resolved
When reviewing, I've asked myself what the actual problem/purpose here is and to me I could come up with 2-3 actual different use-cases:
So basically I just have the gut feeling that we could solve each of those even better, given good design/refactorings. |
These files are used to initialize the assetManager , so it doesn't exist yet at that point. Also it is a good thing they don't use the asset manage features, because they aren't assets, they don't need caching or to be overwritten by things in the asset path.
This change is only related to resources in the classpath, not classes.
If the problem was only with the asset locator, i would have written a new one of my teavm implementation, but this affect various parts of the engine outside of the asset locator and the side effect of this patch is that the default classpath locator becomes automatically compatible.
Maybe, but redesigning all this would take way too much time vs this simple patch that doesn't break anything. |
To enhance compatibility with JVMs that deviate from standard norms and may lack complete or partial support for classloaders (such as teavm), this pull request introduces a new encapsulating class called ResourcesLoader. Functioning analogously to BufferAllocators, this addition empowers developers to specify a personalized implementation. The default implementation, named ResourcesLoaderJImpl, operates by interfacing with the classloader.
Throughout the core, all instances where classloaders were used have been substituted with the utilization of ResourcesLoader, excluding specific parts in GL debug classes and jme3-networking which involve proxies and might need more careful consideration.
The methods within AssetManager that depend on ClassLoader usage have been deprecated and could potentially be marked for removal, as they are not utilized by the engine itself.