1 /** 2 * Copyright (c) 2008, SnakeYAML 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 package org.yaml.snakeyaml.issues.issue318; 15 16 import static org.junit.Assert.assertEquals; 17 import static org.junit.Assert.fail; 18 19 import java.io.File; 20 import java.io.IOException; 21 import java.io.InputStream; 22 import java.lang.reflect.InvocationTargetException; 23 import java.lang.reflect.Method; 24 import java.net.MalformedURLException; 25 import java.net.URL; 26 import java.net.URLClassLoader; 27 import java.util.Properties; 28 import org.junit.After; 29 import org.junit.Before; 30 import org.junit.Test; 31 import org.yaml.snakeyaml.Yaml; 32 33 public class ContextClassLoaderTest { 34 35 static public class DomainBean { 36 37 private int value = 0; 38 setValue(int value)39 public void setValue(int value) { 40 this.value = value; 41 } 42 getValue()43 public int getValue() { 44 return value; 45 } 46 47 @Override hashCode()48 public int hashCode() { 49 final int prime = 31; 50 int result = 1; 51 result = prime * result + value; 52 return result; 53 } 54 55 @Override equals(Object obj)56 public boolean equals(Object obj) { 57 if (this == obj) { 58 return true; 59 } 60 if (obj == null) { 61 return false; 62 } 63 if (getClass() != obj.getClass()) { 64 return false; 65 } 66 DomainBean other = (DomainBean) obj; 67 return value == other.value; 68 } 69 70 } 71 72 private URLClassLoader yamlCL; 73 74 @Before before()75 public void before() throws MalformedURLException { 76 Properties classpath = new Properties(); 77 InputStream cpProperties = getClass().getResourceAsStream("classpath.properties"); 78 try { 79 classpath.load(cpProperties); 80 } catch (IOException e2) { 81 fail(e2.getLocalizedMessage()); 82 } 83 84 File runtimeClassesDir = new File(classpath.getProperty("runtime_classes_dir")); 85 86 ClassLoader noSnakeYAMLClassLoader = 87 new ClassLoader(Thread.currentThread().getContextClassLoader()) { 88 89 @Override 90 protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { 91 if (!name.startsWith("org.yaml.snakeyaml")) { 92 return super.loadClass(name, resolve); 93 } 94 throw new ClassNotFoundException("Can't load SnakeYaml classes by this ClassLoader"); 95 } 96 97 }; 98 99 yamlCL = 100 new URLClassLoader(new URL[] {runtimeClassesDir.toURI().toURL()}, noSnakeYAMLClassLoader); 101 } 102 103 @After after()104 public void after() { 105 if (yamlCL != null) { 106 try { 107 yamlCL.close(); 108 } catch (IOException e) { 109 e.printStackTrace(); 110 } finally { 111 yamlCL = null; 112 } 113 } 114 } 115 116 @Test(expected = ClassNotFoundException.class) expectNoDomainClassInYamlCL()117 public void expectNoDomainClassInYamlCL() throws ClassNotFoundException { 118 yamlCL.loadClass(DomainBean.class.getName()); 119 } 120 121 @Test yamlClassInYAMLCL()122 public void yamlClassInYAMLCL() throws ClassNotFoundException { 123 yamlCL.loadClass(Yaml.class.getName()); 124 } 125 126 @Test domainInDifferentConstructor()127 public void domainInDifferentConstructor() throws ClassNotFoundException, InstantiationException, 128 IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, 129 InvocationTargetException { 130 131 Class<?> yamlClass = yamlCL.loadClass(Yaml.class.getName()); 132 133 DomainBean bean = new DomainBean(); 134 bean.setValue(13); 135 136 Object yaml = yamlClass.newInstance(); 137 138 Method dumpMethod = yaml.getClass().getMethod("dump", Object.class); 139 String dump = dumpMethod.invoke(yaml, bean).toString(); 140 141 Method loadMethod = yaml.getClass().getMethod("load", String.class); 142 DomainBean object = (DomainBean) loadMethod.invoke(yaml, dump); 143 144 assertEquals(bean, object); 145 } 146 147 } 148