View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.pool2.impl;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  
21  import java.net.URL;
22  import java.net.URLClassLoader;
23  import java.time.Duration;
24  
25  import org.apache.commons.pool2.BasePooledObjectFactory;
26  import org.apache.commons.pool2.PooledObject;
27  import org.junit.jupiter.api.Test;
28  
29  public class TestGenericObjectPoolClassLoaders {
30  
31      private static class CustomClassLoader extends URLClassLoader {
32          private final int n;
33  
34          CustomClassLoader(final int n) {
35              super(new URL[] { BASE_URL });
36              this.n = n;
37          }
38  
39          @Override
40          public URL findResource(final String name) {
41              if (!name.endsWith(String.valueOf(n))) {
42                  return null;
43              }
44  
45              return super.findResource(name);
46          }
47      }
48  
49      private static class CustomClassLoaderObjectFactory extends
50              BasePooledObjectFactory<URL> {
51          private final int n;
52  
53          CustomClassLoaderObjectFactory(final int n) {
54              this.n = n;
55          }
56  
57          @Override
58          public URL create() {
59              final URL url = Thread.currentThread().getContextClassLoader()
60                      .getResource("test" + n);
61              if (url == null) {
62                  throw new IllegalStateException("Object should not be null");
63              }
64              return url;
65          }
66  
67          @Override
68          public PooledObject<URL> wrap(final URL value) {
69              return new DefaultPooledObject<>(value);
70          }
71      }
72  
73      private static final URL BASE_URL = TestGenericObjectPoolClassLoaders.class
74              .getResource("/org/apache/commons/pool2/impl/");
75  
76      @Test
77      public void testContextClassLoader() throws Exception {
78  
79          final ClassLoader savedClassloader = Thread.currentThread().getContextClassLoader();
80  
81          try (final CustomClassLoader cl1 = new CustomClassLoader(1)) {
82              Thread.currentThread().setContextClassLoader(cl1);
83              final CustomClassLoaderObjectFactory factory1 = new CustomClassLoaderObjectFactory(1);
84              try (final GenericObjectPool<URL> pool1 = new GenericObjectPool<>(factory1)) {
85                  pool1.setMinIdle(1);
86                  pool1.setDurationBetweenEvictionRuns(Duration.ofMillis(100));
87                  int counter = 0;
88                  while (counter < 50 && pool1.getNumIdle() != 1) {
89                      Thread.sleep(100);
90                      counter++;
91                  }
92                  assertEquals(1, pool1.getNumIdle(), "Wrong number of idle objects in pool1");
93  
94                  try (final CustomClassLoader cl2 = new CustomClassLoader(2)) {
95                      Thread.currentThread().setContextClassLoader(cl2);
96                      final CustomClassLoaderObjectFactory factory2 = new CustomClassLoaderObjectFactory(2);
97                      try (final GenericObjectPool<URL> pool2 = new GenericObjectPool<>(factory2)) {
98                          pool2.setMinIdle(1);
99  
100                         pool2.addObject();
101                         assertEquals(1, pool2.getNumIdle(), "Wrong number of idle objects in pool2");
102                         pool2.clear();
103 
104                         pool2.setDurationBetweenEvictionRuns(Duration.ofMillis(100));
105 
106                         counter = 0;
107                         while (counter < 50 && pool2.getNumIdle() != 1) {
108                             Thread.sleep(100);
109                             counter++;
110                         }
111                         assertEquals(1, pool2.getNumIdle(), "Wrong number of  idle objects in pool2");
112                     }
113                 }
114             }
115         } finally {
116             Thread.currentThread().setContextClassLoader(savedClassloader);
117         }
118     }
119 }