下面列出了怎么用java.net.JarURLConnection的API类实例代码及写法,或者点击链接到github查看源代码。
private static String findJarClassInterface(String packageName, List<Class<?>> classes, String packageDirName, URL url) throws IOException {
JarFile jar = ((JarURLConnection) url.openConnection()).getJarFile();
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String name = entry.getName();
if (name.charAt(0) == '/') { // 如果是以/开头的
name = name.substring(1);// 获取后面的字符串
}
// 如果前半部分和定义的包名相同
if (name.startsWith(packageDirName)) {
int lastIndex = name.lastIndexOf('/');
if (lastIndex != -1) { // 如果以"/"结尾,就是是一个包
// 获取包名 把"/"替换成"."
packageName = name.substring(0, lastIndex).replace('/', '.');
}
// 如果是一个.class文件,而且不是目录
if (lastIndex != -1 && name.endsWith(".class") && !entry.isDirectory()) {
String className = packageName + '.' + name.substring(packageName.length() + 1, name.length() - 6);
putInterface(className, classes);
}
}
}
return packageName;
}
private XMLStreamReader parse(URL url, boolean restricted)
throws IOException, XMLStreamException {
if (!quietmode) {
if (LOG.isDebugEnabled()) {
LOG.debug("parsing URL " + url);
}
}
if (url == null) {
return null;
}
URLConnection connection = url.openConnection();
if (connection instanceof JarURLConnection) {
// Disable caching for JarURLConnection to avoid sharing JarFile
// with other users.
connection.setUseCaches(false);
}
return parse(connection.getInputStream(), url.toString(), restricted);
}
private void findClassInJar(Collection<String> classNameList, URL url, String packagePath) throws IOException {
JarFile jarFile = null;
try {
URLConnection conn = url.openConnection();
if (!JarURLConnection.class.isInstance(conn)) {
Logs.system().error("the connection of {} is {}", url.getPath(), conn.getClass().getName());
SumkException.throwException(25345643, conn.getClass().getName() + " is not JarURLConnection");
}
jarFile = ((JarURLConnection) conn).getJarFile();
Enumeration<JarEntry> jarEntryEnum = jarFile.entries();
while (jarEntryEnum.hasMoreElements()) {
String entityName = jarEntryEnum.nextElement().getName();
if (entityName.startsWith("/")) {
entityName = entityName.substring(1);
}
if (entityName.startsWith(packagePath)) {
addClz(classNameList, entityName);
}
}
} finally {
if (jarFile != null) {
jarFile.close();
}
}
}
public static void main( String[] args ) throws IOException {
JarOutputStream out = new JarOutputStream(
new FileOutputStream("usecache.jar"));
out.putNextEntry(new JarEntry("test.txt"));
out.write("Test txt file".getBytes());
out.closeEntry();
out.close();
URL url = new URL("jar:"
+ new File(".").toURI().toString()
+ "/usecache.jar!/test.txt");
JarURLConnection c1 = (JarURLConnection)url.openConnection();
c1.setDefaultUseCaches( false );
c1.setUseCaches( true );
c1.connect();
JarURLConnection c2 = (JarURLConnection)url.openConnection();
c2.setDefaultUseCaches( false );
c2.setUseCaches( true );
c2.connect();
c1.getInputStream().close();
c2.getInputStream().read();
c2.getInputStream().close();
}
private XMLStreamReader parse(URL url, boolean restricted)
throws IOException, XMLStreamException {
if (!quietmode) {
if (LOG.isDebugEnabled()) {
LOG.debug("parsing URL " + url);
}
}
if (url == null) {
return null;
}
URLConnection connection = url.openConnection();
if (connection instanceof JarURLConnection) {
// Disable caching for JarURLConnection to avoid sharing JarFile
// with other users.
connection.setUseCaches(false);
}
return parse(connection.getInputStream(), url.toString(), restricted);
}
private InputStream getInputStream(final URL resource) throws IOException {
final URLConnection urlc = resource.openConnection();
final InputStream is = urlc.getInputStream();
if (JarURLConnection.class.isInstance(urlc)) {
final JarURLConnection juc = JarURLConnection.class.cast(urlc);
final JarFile jar = juc.getJarFile();
synchronized (closeables) {
if (!closeables.containsKey(jar)) {
closeables.put(jar, null);
}
}
} else if (urlc.getClass().getName().equals("sun.net.www.protocol.file.FileURLConnection")) {
synchronized (closeables) {
closeables.put(is, null);
}
}
return is;
}
public static void main( String[] args ) throws IOException {
JarOutputStream out = new JarOutputStream(
new FileOutputStream("usecache.jar"));
out.putNextEntry(new JarEntry("test.txt"));
out.write("Test txt file".getBytes());
out.closeEntry();
out.close();
URL url = new URL("jar:"
+ new File(".").toURI().toString()
+ "/usecache.jar!/test.txt");
JarURLConnection c1 = (JarURLConnection)url.openConnection();
c1.setDefaultUseCaches( false );
c1.setUseCaches( true );
c1.connect();
JarURLConnection c2 = (JarURLConnection)url.openConnection();
c2.setDefaultUseCaches( false );
c2.setUseCaches( true );
c2.connect();
c1.getInputStream().close();
c2.getInputStream().read();
c2.getInputStream().close();
}
protected void findClasses(Set<Class<?>> classes, ClassLoader classLoader,
String packageName, JarURLConnection connection) throws IOException {
JarFile jarFile = connection.getJarFile();
if (jarFile == null) {
return;
}
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String name = entry.getName();
if (name.endsWith(CLASS_SUFFIX) && name.startsWith(packageName)) {
String className = name.replace('/', '.').replace(CLASS_SUFFIX, "");
try {
Class<?> c = ClassUtils.forName(className, classLoader);
classes.add(c);
} catch (ClassNotFoundException e) {
// ignore
e.printStackTrace();
}
}
}
}
/**
* scan the all class file in the package
*
* @param pkg
* @return
*/
public static Set<Class<?>> getClzFromPkg(String pkg) {
Set<Class<?>> classes = new LinkedHashSet<>();
String pkgDirName = pkg.replace('.', '/');
try {
Enumeration<URL> urls = PackageUtil.class.getClassLoader().getResources(pkgDirName);
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
String protocol = url.getProtocol();
if ("file".equals(protocol)) {//
String filePath = URLDecoder.decode(url.getFile(), Constants.ENCODING_UTF8);//
findClassesByFile(pkg, filePath, classes);
} else if ("jar".equals(protocol)) {//
JarFile jar = ((JarURLConnection) url.openConnection()).getJarFile();
findClassesByJar(pkg, jar, classes);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return classes;
}
@Override
public Vfs.Dir createDir(final URL url) throws Exception {
URLConnection urlConnection = url.openConnection();
Class<?> theClass = warURLConnectionClass.get();
if (urlConnection.getClass().equals(theClass)) {
Object wrappedJarUrlConnection = getValue(
makeAccessible(
theClass.getDeclaredField("wrappedJarUrlConnection")
),
urlConnection
);
if (wrappedJarUrlConnection instanceof JarURLConnection) {
return new ZipDir(((JarURLConnection) wrappedJarUrlConnection).getJarFile());
}
}
return null;
}
private List<JavaFileObject> processJar(URL packageFolderURL) {
List<JavaFileObject> result = new ArrayList<JavaFileObject>();
try {
String jarUri = packageFolderURL.toExternalForm().substring(0, packageFolderURL.toExternalForm().lastIndexOf("!/"));
JarURLConnection jarConn = (JarURLConnection) packageFolderURL.openConnection();
String rootEntryName = jarConn.getEntryName();
int rootEnd = rootEntryName.length() + 1;
Enumeration<JarEntry> entryEnum = jarConn.getJarFile().entries();
while (entryEnum.hasMoreElements()) {
JarEntry jarEntry = entryEnum.nextElement();
String name = jarEntry.getName();
if (name.startsWith(rootEntryName) && name.indexOf('/', rootEnd) == -1 && name.endsWith(CLASS_FILE_EXTENSION)) {
URI uri = URI.create(jarUri + "!/" + name);
String binaryName = name.replaceAll("/", ".");
binaryName = binaryName.replaceAll(CLASS_FILE_EXTENSION + "$", "");
result.add(new CustomJavaFileObject(binaryName, uri));
}
}
} catch (Exception e) {
throw new RuntimeException("Wasn't able to open " + packageFolderURL + " as a jar file", e);
}
return result;
}
@Override
public JarContents<ClassNode> load() throws IOException {
JarContents<ClassNode> contents = new JarContents<ClassNode>();
JarURLConnection con = (JarURLConnection) getLocation().openConnection();
JarFile jar = con.getJarFile();
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
byte[] bytes = read(jar.getInputStream(entry));
if (entry.getName().endsWith(".class")) {
ClassNode cn = create(bytes);
contents.getClassContents().add(cn);
} else {
JarResource resource = new JarResource(entry.getName(), bytes);
contents.getResourceContents().add(resource);
}
}
return contents;
}
/**
* Return a time-stamp showing When was the JAR file
* created OR when was a class compiled
*/
public static String compileTimeStamp(Class<?> cl) {
try {
String resName = cl.getName().replace('.', '/') + ".class";
URLConnection conn = ClassLoader.getSystemResource(resName).openConnection();
long epoch = 0;
if (conn instanceof JarURLConnection) {
// Is it a JAR file? Get manifest time
epoch = ((JarURLConnection) conn).getJarFile().getEntry("META-INF/MANIFEST.MF").getTime();
} else {
// Regular file? Get file compile time
epoch = conn.getLastModified();
}
// Format as timestamp
Date epochDate = new Date(epoch);
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
return df.format(epochDate);
} catch (Exception e) {
return null;
}
}
public Set<Class<?>> findCandidateClasses(String basePackage) {
Set<Class<?>> candidates = new LinkedHashSet<Class<?>>();
try {
String packageSearchPath = basePackage.replace('.', '/');
ClassLoader classLoader = this.classLoader;
if (classLoader == null) {
classLoader = Thread.currentThread().getContextClassLoader();
}
Enumeration<URL> resources = classLoader.getResources(packageSearchPath);
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
if (logger.isTraceEnabled()) {
logger.trace("Scanning " + resource);
}
if ("file".equals(resource.getProtocol())) {
findClasses(candidates, classLoader, basePackage, resource.getFile());
} else if ("jar".equals(resource.getProtocol())) {
findClasses(candidates, classLoader, packageSearchPath, (JarURLConnection) resource.openConnection());
}
}
} catch (IOException e) {
throw new RuntimeException("I/O failure during classpath scanning", e);
}
return candidates;
}
private static List<Class<?>> getClassesFromJar(URL url, String basePack) throws IOException, ClassNotFoundException {
List<Class<?>> classes = new ArrayList<>();
JarURLConnection connection = (JarURLConnection) url.openConnection();
if (connection != null) {
JarFile jarFile = connection.getJarFile();
if (jarFile != null) {
//得到该jar文件下面的类实体
Enumeration<JarEntry> jarEntryEnumeration = jarFile.entries();
while (jarEntryEnumeration.hasMoreElements()) {
JarEntry entry = jarEntryEnumeration.nextElement();
String jarEntryName = entry.getName();
//这里我们需要过滤不是class文件和不在basePack包名下的类
if (jarEntryName.contains(".class") && jarEntryName.replaceAll("/", ".").startsWith(basePack)) {
String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replace("/", ".");
Class cls = Class.forName(className);
classes.add(cls);
}
}
}
}
return classes;
}
public PackageScanner(final String... packageNames) {
for (String packageName : packageNames) {
try {
final String packageDirectory = packageName.replace('.', '/');
final Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(packageDirectory);
while (urls.hasMoreElements()) {
final URL url = urls.nextElement();
if ("file".equals(url.getProtocol())) {
final File directory = new File(url.getPath());
if (!directory.isDirectory()) {
throw new RuntimeException("package:[" + packageName + "] is not directory");
}
clazzCollection.addAll(PackageUtility.scanClassByDirectory(packageName, directory));
} else if ("jar".equals(url.getProtocol())) {
final JarFile jar = ((JarURLConnection) url.openConnection()).getJarFile();
clazzCollection.addAll(PackageUtility.scanClassByJar(packageName, jar));
}
}
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
}
/**
* Validate the WAR file found at the specified URL.
*
* @param host Host war is being installed for
* @param war URL of the web application archive to be validated
* (must start with "jar:")
* @param pathname Context path name for web application
*
* @exception IllegalArgumentException if this is not a "jar:" URL or if the
* WAR file is invalid
* @exception IOException if an input/output error was encountered
* during validation
*/
public static void validate(Host host, URL war, String pathname) throws IOException {
File docBase = new File(host.getAppBaseFile(), pathname);
// Calculate the document base directory
String canonicalDocBasePrefix = docBase.getCanonicalPath();
if (!canonicalDocBasePrefix.endsWith(File.separator)) {
canonicalDocBasePrefix += File.separator;
}
JarURLConnection juc = (JarURLConnection) war.openConnection();
juc.setUseCaches(false);
try (JarFile jarFile = juc.getJarFile()) {
Enumeration<JarEntry> jarEntries = jarFile.entries();
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
String name = jarEntry.getName();
File expandedFile = new File(docBase, name);
if (!expandedFile.getCanonicalPath().startsWith(
canonicalDocBasePrefix)) {
// Entry located outside the docBase
// Throw an exception to stop the deployment
throw new IllegalArgumentException(
sm.getString("expandWar.illegalPath",war, name,
expandedFile.getCanonicalPath(),
canonicalDocBasePrefix));
}
}
} catch (IOException e) {
throw e;
}
}
public static boolean copyJarResourcesRecursively(
final File destDir, final JarURLConnection jarConnection
) throws IOException {
final JarFile jarFile = jarConnection.getJarFile();
for (final Enumeration<JarEntry> e = jarFile.entries(); e.hasMoreElements(); ) {
final JarEntry entry = e.nextElement();
if (entry.getName().startsWith(jarConnection.getEntryName())) {
final String filename = StringUtils.removeStart(
entry.getName(), //
jarConnection.getEntryName());
final File f = new File(destDir, filename);
if (!entry.isDirectory()) {
final InputStream entryInputStream = jarFile.getInputStream(entry);
if (!FileUtils.copyStream(entryInputStream, f)) {
return false;
}
entryInputStream.close();
} else {
if (!FileUtils.ensureDirectoryExists(f)) {
throw new IOException("Could not create directory: " + f.getAbsolutePath());
}
}
}
}
return true;
}
public static Long getBuildTime(Class<?> cl) {
try {
String rn = cl.getName().replace('.', '/') + ".class";
JarURLConnection j = (JarURLConnection) ClassLoader.getSystemResource(rn).openConnection();
return j.getJarFile().getEntry("META-INF/MANIFEST.MF").getTime();
} catch (Exception e) {
return 0L;
}
}
static void check(URL url) throws IOException {
SecurityManager security = System.getSecurityManager();
if (security != null) {
URLConnection urlConnection = url.openConnection();
Permission perm = urlConnection.getPermission();
if (perm != null) {
try {
security.checkPermission(perm);
} catch (SecurityException se) {
// fallback to checkRead/checkConnect for pre 1.2
// security managers
if ((perm instanceof java.io.FilePermission) &&
perm.getActions().indexOf("read") != -1) {
security.checkRead(perm.getName());
} else if ((perm instanceof
java.net.SocketPermission) &&
perm.getActions().indexOf("connect") != -1) {
URL locUrl = url;
if (urlConnection instanceof JarURLConnection) {
locUrl = ((JarURLConnection)urlConnection).getJarFileURL();
}
security.checkConnect(locUrl.getHost(),
locUrl.getPort());
} else {
throw se;
}
}
}
}
}
private boolean isRuntimeClass(URLConnection conn) throws IOException {
final URL url = conn.getURL();
if (isRuntimePath(url)) {
return true;
} else if ("jar".equalsIgnoreCase(url.getProtocol()) && conn instanceof JarURLConnection) {
final URL jarUrl = ((JarURLConnection) conn).getJarFileURL();
return isRuntimePath(jarUrl);
} else if ("jrt".equalsIgnoreCase(url.getProtocol())) {
// all 'jrt:' URLs refer to a module in the Java 9+ runtime (see http://openjdk.java.net/jeps/220)
return AsmUtils.isRuntimeModule(AsmUtils.getModuleName(url));
}
return false;
}
/**
* 加载指定包下符合条件的class
*
* @param pkgName java包名,eg: com.wjybxx.game
* @param classNameFilter 过滤要加载的类,避免加载过多无用的类 test返回true的才会加载
* @param classFilter 对加载后的类进行再次确认 test返回true的才会添加到结果集中
* @return 符合过滤条件的class文件
*/
public static Set<Class<?>> findClasses(String pkgName, Predicate<String> classNameFilter, Predicate<Class<?>> classFilter) {
//第一个class类的集合
Set<Class<?>> classes = new LinkedHashSet<>();
// 获取文件路径
String pkgDirName = pkgName.replace('.', '/');
try {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Enumeration<URL> urls = classLoader.getResources(pkgDirName);
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
// 得到协议的名称
String protocol = url.getProtocol();
// 如果是以文件的形式保存在服务器上 file:
if ("file".equals(protocol)) {
// 获取包的物理路径
String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
// 以文件的方式扫描整个包下的文件 并添加到集合中
findClassesByFile(classLoader, pkgName, filePath, classes, classNameFilter, classFilter);
} else if ("jar".equals(protocol)) {
// 如果是jar包文件 jar:
JarFile jar = ((JarURLConnection) url.openConnection()).getJarFile();
//扫描jar包文件 并添加到集合中
findClassesByJar(classLoader, pkgName, jar, classes, classNameFilter, classFilter);
}
}
} catch (IOException e) {
logger.warn("scanner pkgName {} caught exception.", pkgName, e);
}
return classes;
}
public static void copyResourcesRecursively(URL originUrl, File destination) throws Exception {
URLConnection urlConnection = originUrl.openConnection();
if (urlConnection instanceof JarURLConnection) {
copyJarResourcesRecursively(destination, (JarURLConnection) urlConnection);
} else if (urlConnection instanceof FileURLConnection) {
FileUtils.copyDirectory(new File(originUrl.getPath()), destination);
} else {
die("Unsupported URL type: " + urlConnection);
}
}
private JarFile getJarFile(URL jarFileUrl) throws IOException {
JarFile jarFile = null;
if (jarFileUrl != null) {
JarURLConnection conn = (JarURLConnection) jarFileUrl.openConnection();
conn.setUseCaches(false);
conn.connect();
jarFile = conn.getJarFile();
}
return jarFile;
}
private static List<String> findResourcePaths(String moduleName) throws ModuleLoadException, ReflectiveOperationException, IOException, URISyntaxException {
ModuleLoader moduleLoader = Module.getCallerModuleLoader();
ModuleLoaderMXBean loader = ModuleInfoHandler.INSTANCE.getMxBean(moduleLoader);
moduleLoader.loadModule(ModuleIdentifier.fromString(moduleName));
List<String> result = new LinkedList<>();
for (ResourceLoaderInfo rl : loader.getResourceLoaders(moduleName)){
if (rl.getLocation() != null) {
URL url = new URL(rl.getLocation());
switch (url.getProtocol()){
case "jar": {
JarURLConnection jarConnection = (JarURLConnection)url.openConnection();
result.add(jarConnection.getJarFile().getName());
break;
}
default: {
result.add(new File(url.getFile() ).toString());
}
}
}
}
return result;
}
public static boolean urlExists(URL url) {
try {
URLConnection connection = url.openConnection();
if ( connection instanceof JarURLConnection ) {
JarURLConnection jarURLConnection = (JarURLConnection)connection;
URLClassLoader urlClassLoader = new URLClassLoader(new URL[] {
jarURLConnection.getJarFileURL()
});
try { return urlClassLoader.findResource(jarURLConnection.getEntryName())!=null; }
finally {
if ( urlClassLoader instanceof Closeable ) {
((Closeable)urlClassLoader).close();
}
}
}
InputStream is = null;
try {
is = url.openStream();
}
finally {
if ( is!=null ) {
is.close();
}
}
return is!=null;
}
catch (IOException ioe) { return false; }
}
private JarFile findJarFile(URL url) throws IOException {
// Optimize case where url refers to a local jar file
if ("file".equals(url.getProtocol())) {
String path = url.getFile().replace('/', File.separatorChar);
File file = new File(path);
if (!file.exists()) {
throw new FileNotFoundException(path);
}
return new JarFile(path);
}
URLConnection uc = getBaseURL().openConnection();
//uc.setRequestProperty(USER_AGENT_JAVA_VERSION, JAVA_VERSION);
return ((JarURLConnection)uc).getJarFile();
}
private JarFile findJarFile(URL url) throws IOException {
// Optimize case where url refers to a local jar file
if ("file".equals(url.getProtocol())) {
String path = url.getFile().replace('/', File.separatorChar);
File file = new File(path);
if (!file.exists()) {
throw new FileNotFoundException(path);
}
return new JarFile(path);
}
URLConnection uc = getBaseURL().openConnection();
//uc.setRequestProperty(USER_AGENT_JAVA_VERSION, JAVA_VERSION);
return ((JarURLConnection)uc).getJarFile();
}
private JarFile getJarFile(URL url) throws IOException {
// Optimize case where url refers to a local jar file
if (isOptimizable(url)) {
FileURLMapper p = new FileURLMapper (url);
if (!p.exists()) {
throw new FileNotFoundException(p.getPath());
}
return checkJar(new JarFile(p.getPath()));
}
URLConnection uc = getBaseURL().openConnection();
uc.setRequestProperty(USER_AGENT_JAVA_VERSION, JAVA_VERSION);
JarFile jarFile = ((JarURLConnection)uc).getJarFile();
return checkJar(jarFile);
}
/**
* @param packNames 要扫描的包
* @return Set
*/
public static Set<Class<?>> findFileClass(String... packNames) {
Set<Class<?>> clazzs = new LinkedHashSet<Class<?>>();
for (String packName : packNames) {
String packageDirName = packName.replace('.', '/');
Enumeration<URL> dirs;
try {
dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
while (dirs.hasMoreElements()) {
URL url = dirs.nextElement();
String protocol = url.getProtocol();
if ("file".equals(protocol)) {
//扫描file包中的类
String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
getFileClass(packName, filePath, clazzs);
} else if ("jar".equals(protocol)) {
//扫描jar包中的类
JarFile jarFile = ((JarURLConnection) url.openConnection()).getJarFile();
getJarClass(jarFile, packageDirName, clazzs);
}
}
} catch (Exception e) {
e.getStackTrace();
}
}
return clazzs;
}