org.javafmi.kernel.JarClassLoader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fmu-wrapper Show documentation
Show all versions of fmu-wrapper Show documentation
javaFMI is a Java Library for the functional mock-up interface (or FMI). FMI defines a standardized interface to be used in computer simulations. The FMI Standard has beed developed by a large number of software companies and research centers that have worked in a cooperation project under the name of MODELISAR. This library addresses the connection of a java application with a FMU (functional mock-up unit).
/*
* Copyright 2013-2016 SIANI - ULPGC
*
* This File is part of JavaFMI Project
*
* JavaFMI Project is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License.
*
* JavaFMI Project is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with JavaFMI. If not, see .
*/
package org.javafmi.kernel;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.javafmi.kernel.Files.close;
import static org.javafmi.kernel.Files.copyFromTo;
public class JarClassLoader extends ClassLoader {
private File jarFile;
private File outFolder;
private static List javaPackagePatterns = new ArrayList<>(Arrays.asList("java.", "sun.", "javax.", "com.sun."));
public JarClassLoader(File jarFile) {
this.jarFile = jarFile;
this.outFolder = getTempDirectory().toFile();
}
public Path getTempDirectory() {
try {
return Files.createTempDirectory(getClass().getName());
} catch (IOException e) {
throw new RuntimeException("Impossible to create temp directory to extract " + jarFile.getName());
}
}
public Class loadClass(String className) {
if (isAFrameworkClass(className) || isAJavaClass(className)) return loadCLassUsingSuperClassLoader(className);
byte[] classData = getClassBytes(getClassUrl(replaceDotWithSlash(className)));
return defineClass(className, classData, 0, classData.length);
}
public boolean isAFrameworkClass(String className) {
return className.startsWith("org.javafmi.framework");
}
public boolean isAJavaClass(String className) {
for (String javaPackagePattern : javaPackagePatterns) if (className.startsWith(javaPackagePattern)) return true;
return false;
}
public static void registerJavaPackage(String aPackage) {
javaPackagePatterns.add(aPackage);
}
public URL getResource(String name) {
try {
return new Unzipper(jarFile).unzip(name, outFolder).toURI().toURL();
} catch (Exception e) {
return super.getResource(name);
}
}
private Class loadCLassUsingSuperClassLoader(String className) {
try {
return super.loadClass(className);
} catch (ClassNotFoundException e) {
try {
return this.getClass().getClassLoader().loadClass(className);
} catch (ClassNotFoundException ignored) {
}
throw new RuntimeException(e);
}
}
private String replaceDotWithSlash(String className) {
while (className.indexOf('.') > 0)
className = className.replace('.', '/');
return className;
}
public URL getClassUrl(String className) {
try {
return new Unzipper(jarFile).unzip(className + ".class", outFolder).toURI().toURL();
} catch (IOException e) {
throw new RuntimeException("Problem getting the class URL " + className);
}
}
private byte[] getClassBytes(URL classUrl) {
InputStream input = getInputStreamFromConnection(classUrl);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
copyFromTo(input, buffer);
close(input);
close(buffer);
return buffer.toByteArray();
}
private URLConnection openConnection(URL classUrl) {
try {
return classUrl.openConnection();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private InputStream getInputStreamFromConnection(URL classUrl) {
try {
return openConnection(classUrl).getInputStream();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy