Skip to content

Commit

Permalink
🐛 fix: #10 classes loading from a jar can't be load
Browse files Browse the repository at this point in the history
  • Loading branch information
TAKETODAY committed Jul 21, 2019
1 parent 05e5a29 commit 6aad09a
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 55 deletions.
1 change: 0 additions & 1 deletion src/main/java/cn/taketoday/context/Constant.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ public interface Constant extends Serializable {
/**********************************************
* @since 2.1.2
*/
String FREAMWORK_PACKAGE = "cn.taketoday";
String CLASS_PATH_PREFIX = "classpath:";
String INIT_METHODS = "initMethods";
String DESTROY_METHODS = "destroyMethods";
Expand Down
83 changes: 34 additions & 49 deletions src/main/java/cn/taketoday/context/utils/ClassUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ public abstract class ClassUtils {
private static final Set<Class<? extends Annotation>> IGNORE_ANNOTATION_CLASS = new HashSet<>();//

private static final String[] IGNORE_SCAN_JARS;
/** for scan cn.taketoday */
private static boolean scanAllFreamworkPackage = true;

private static boolean ignoreScanJarsPrefix = true;

private static final ParameterFunction PARAMETER_NAMES_FUNCTION = new ParameterFunction();
private static final Map<Class<?>, Map<Method, String[]>> PARAMETER_NAMES_CACHE = new HashMap<>(256);
Expand Down Expand Up @@ -185,10 +185,6 @@ public static void addIgnoreAnnotationClass(Class<? extends Annotation> annotati
IGNORE_ANNOTATION_CLASS.add(annotationClass);
}

public static void setScanAllFreamworkPackage(final boolean scanAllFreamworkPackage) {
ClassUtils.scanAllFreamworkPackage = scanAllFreamworkPackage;
}

public static final boolean isCollection(Class<?> cls) {
return Collection.class.isAssignableFrom(cls);
}
Expand All @@ -211,6 +207,14 @@ public static ClassLoader getClassLoader() {
return ClassUtils.classLoader;
}

public static boolean isIgnoreScanJarsPrefix() {
return ignoreScanJarsPrefix;
}

public static void setIgnoreScanJarsPrefix(boolean ignoreScanJars) {
ClassUtils.ignoreScanJarsPrefix = ignoreScanJars;
}

/**
* get all classes loaded in class path
*/
Expand Down Expand Up @@ -411,7 +415,7 @@ public static Set<Class<?>> getClasses(final String... packages) {
return filter(clazz -> {
final String name = clazz.getName();
for (final String prefix : packages) {
if (StringUtils.isEmpty(prefix) || name.startsWith(prefix) || name.startsWith(Constant.FREAMWORK_PACKAGE)) {
if (StringUtils.isEmpty(prefix) || name.startsWith(prefix)) {
return true;
}
}
Expand All @@ -427,6 +431,7 @@ public static Set<Class<?>> getClasses(final String... packages) {
* @return Class set
*/
public static Set<Class<?>> scan(final String... packages) {

Objects.requireNonNull(packages, "scan package can't be null");

if (classesCache == null || classesCache.isEmpty()) {
Expand All @@ -436,14 +441,10 @@ public static Set<Class<?>> scan(final String... packages) {
scanOne(scanClasses, packages[0]); // packages.length == 1
}
else {
final Set<String> packagesToScan = new HashSet<>();
final Set<String> packagesToScan = new HashSet<>(8);
for (final String location : packages) {

if (scanAllFreamworkPackage && location.startsWith(Constant.FREAMWORK_PACKAGE)) {
// maybe cn.taketoday.xxx will scan all cn.taketoday
packagesToScan.add(Constant.FREAMWORK_PACKAGE);
}
else if (StringUtils.isEmpty(location)) { // contains "" scan all class
if (StringUtils.isEmpty(location)) { // contains "" scan all class
scan(scanClasses);
setClassCache(scanClasses);
return scanClasses;
Expand All @@ -452,9 +453,6 @@ else if (StringUtils.isEmpty(location)) { // contains "" scan all class
packagesToScan.add(location);
}
}
if (scanAllFreamworkPackage) {
packagesToScan.add(Constant.FREAMWORK_PACKAGE);
}
for (final String location : packagesToScan) {
scan(scanClasses, location);
}
Expand All @@ -465,23 +463,13 @@ else if (StringUtils.isEmpty(location)) { // contains "" scan all class
return getClasses(packages);
}

private static void scanOne(final Set<Class<?>> scanClasses, final String location) {
protected static void scanOne(final Set<Class<?>> scanClasses, final String location) {

if (StringUtils.isEmpty(location)) {
scan(scanClasses);
}
else {
if (scanAllFreamworkPackage) {

if (!location.startsWith(Constant.FREAMWORK_PACKAGE)) {
scan(scanClasses, location);
}
// cn.taketoday.xx
scan(scanClasses, Constant.FREAMWORK_PACKAGE);
}
else {
scan(scanClasses, location);
}
scan(scanClasses, location);
}
}

Expand Down Expand Up @@ -549,9 +537,11 @@ else if (resource instanceof JarEntryResource) {
private static void scanInJarFile(final Collection<Class<?>> scanClasses, final Resource resource, //
final String fileName, String packageName, final ThrowableSupplier<JarFile, IOException> supplier) throws IOException//
{
for (final String ignoreJarName : IGNORE_SCAN_JARS) {
if (fileName.startsWith(ignoreJarName)) {
return;
if (ignoreScanJarsPrefix) {
for (final String ignoreJarName : IGNORE_SCAN_JARS) {
if (fileName.startsWith(ignoreJarName)) {
return;
}
}
}
if (traceEnabled) {
Expand Down Expand Up @@ -604,29 +594,24 @@ public static void scan(Collection<Class<?>> scanClasses) {
* class set
*/
public static void loadClassInJar(JarEntry jarEntry, String packageName, Collection<Class<?>> scanClasses) {
final String jarEntryName = jarEntry.getName();

if (jarEntry.isDirectory() || //
jarEntryName.startsWith("module-info") || //
jarEntryName.startsWith("package-info") || //
!jarEntryName.endsWith(Constant.CLASS_FILE_SUFFIX)) {
if (jarEntry.isDirectory()) {
return;
}
final String jarEntryName = jarEntry.getName(); // cn/taketoday/xxx/yyy.class
if (jarEntryName.endsWith(Constant.CLASS_FILE_SUFFIX)) {

if (StringUtils.isNotEmpty(packageName) && //
!jarEntryName.startsWith(packageName) && //
(!scanAllFreamworkPackage || !jarEntryName.startsWith(Constant.FREAMWORK_PACKAGE))) {
return;
}
// fix #10 classes loading from a jar can't be load @off
final String nameToUse = jarEntryName.replace(Constant.PATH_SEPARATOR, Constant.PACKAGE_SEPARATOR);

try {
scanClasses.add(classLoader.loadClass(//
jarEntryName.substring(0, jarEntryName.lastIndexOf(Constant.PACKAGE_SEPARATOR))//
.replace(Constant.PATH_SEPARATOR, Constant.PACKAGE_SEPARATOR)//
));
}
catch (Error | ClassNotFoundException e) {
// log.warn("[{}] Occur , With Msg:[{}]", e, e.getMessage());
if (StringUtils.isEmpty(packageName) || nameToUse.startsWith(packageName)) {
try {
scanClasses.add(classLoader.loadClass(//
nameToUse.substring(0, nameToUse.lastIndexOf(Constant.PACKAGE_SEPARATOR))//
));
}
catch (Error | ClassNotFoundException e) {} //@on
}
}
}

Expand Down
12 changes: 7 additions & 5 deletions src/test/java/test/context/utils/ClassUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,13 @@ public void test_Scan() {
ClassUtils.setClassCache(null);

final Set<Class<?>> scan2 = ClassUtils.scan("com.sun.el");
assert scan2.size() != 0;
assert scan2.size() == 0;

ClassUtils.setClassCache(null);
ClassUtils.setIgnoreScanJarsPrefix(false);
final Set<Class<?>> scan3 = ClassUtils.scan("com.sun.el");
assert scan3.size() != 0;
ClassUtils.setIgnoreScanJarsPrefix(true);

ClassUtils.setClassCache(null);
final Set<Class<?>> scanEmpty = ClassUtils.scan("cn.taketoday", "");
Expand All @@ -120,12 +126,8 @@ public void test_Scan() {

assert ClassUtils.scan("").size() > 0; // for scanOne

ClassUtils.setScanAllFreamworkPackage(false);

assert ClassUtils.scan("").size() > 0; // for scanOne

ClassUtils.setScanAllFreamworkPackage(true);

ClassUtils.clearCache();
assert ClassUtils.scan("cn.taketoday").size() == ClassUtils.getClasses("cn.taketoday").size();
}
Expand Down

0 comments on commit 6aad09a

Please sign in to comment.