Compare commits

...

1049 Commits

Author SHA1 Message Date
Sam Brannen a636420239 Manual URL Cleanup
See gh-22517
2019-03-12 17:44:26 +01:00
Sam Brannen e68a7ae776 Merge branch 'spring-operator-polish-urls-build-4.0.x' into 4.0.x 2019-03-11 22:40:02 +01:00
Sam Brannen 0dedba016c Manual URL Cleanup
Closes gh-22517
2019-03-11 20:34:33 +01:00
Spring Operator 82ee0bef93 URL Cleanup
This commit updates URLs to prefer the https protocol. Redirects are not followed to avoid accidentally expanding intentionally shortened URLs (i.e. if using a URL shortener).

# HTTP URLs that Could Not Be Fixed
These URLs were unable to be fixed. Please review them to see if they can be manually resolved.

* http://aopalliance.sourceforge.net/doc/ (200) migrated to:
  http://aopalliance.sourceforge.net/doc/ ([https](https://aopalliance.sourceforge.net/doc/) result AnnotatedConnectException).

# Fixed URLs

## Fixed But Review Recommended
These URLs were fixed, but the https status was not OK. However, the https status was the same as the http request or http redirected to an https URL, so they were migrated. Your review is recommended.

* http://jackson.codehaus.org/1.9.4/javadoc/ (UnknownHostException) migrated to:
  https://jackson.codehaus.org/1.9.4/javadoc/ ([https](https://jackson.codehaus.org/1.9.4/javadoc/) result UnknownHostException).
* http://jira.codehaus.org/browse/JIBX-465 (UnknownHostException) migrated to:
  https://jira.codehaus.org/browse/JIBX-465 ([https](https://jira.codehaus.org/browse/JIBX-465) result UnknownHostException).
* http://quartz-scheduler.org/api/2.2.0/ (301) migrated to:
  https://www.quartz-scheduler.org/api/2.2.0/ ([https](https://quartz-scheduler.org/api/2.2.0/) result 404).

## Fixed Success
These URLs were fixed successfully.

* http://commons.apache.org/proper/commons-codec/apidocs/ migrated to:
  https://commons.apache.org/proper/commons-codec/apidocs/ ([https](https://commons.apache.org/proper/commons-codec/apidocs/) result 200).
* http://commons.apache.org/proper/commons-dbcp/apidocs/ migrated to:
  https://commons.apache.org/proper/commons-dbcp/apidocs/ ([https](https://commons.apache.org/proper/commons-dbcp/apidocs/) result 200).
* http://commons.apache.org/proper/commons-lang/javadocs/api-2.5/ migrated to:
  https://commons.apache.org/proper/commons-lang/javadocs/api-2.5/ ([https](https://commons.apache.org/proper/commons-lang/javadocs/api-2.5/) result 200).
* http://docs.jboss.org/jbossas/javadoc/4.0.5/connector/ migrated to:
  https://docs.jboss.org/jbossas/javadoc/4.0.5/connector/ ([https](https://docs.jboss.org/jbossas/javadoc/4.0.5/connector/) result 200).
* http://docs.jboss.org/jbossas/javadoc/7.1.2.Final/ migrated to:
  https://docs.jboss.org/jbossas/javadoc/7.1.2.Final/ ([https](https://docs.jboss.org/jbossas/javadoc/7.1.2.Final/) result 200).
* http://docs.oracle.com/cd/E13222_01/wls/docs90/javadocs/ migrated to:
  https://docs.oracle.com/cd/E13222_01/wls/docs90/javadocs/ ([https](https://docs.oracle.com/cd/E13222_01/wls/docs90/javadocs/) result 200).
* http://docs.oracle.com/javaee/7/api/ migrated to:
  https://docs.oracle.com/javaee/7/api/ ([https](https://docs.oracle.com/javaee/7/api/) result 200).
* http://docs.oracle.com/javase/7/docs/api/ migrated to:
  https://docs.oracle.com/javase/7/docs/api/ ([https](https://docs.oracle.com/javase/7/docs/api/) result 200).
* http://portals.apache.org/pluto/portlet-2.0-apidocs/ migrated to:
  https://portals.apache.org/pluto/portlet-2.0-apidocs/ ([https](https://portals.apache.org/pluto/portlet-2.0-apidocs/) result 200).
* http://tiles.apache.org/framework/apidocs/ migrated to:
  https://tiles.apache.org/framework/apidocs/ ([https](https://tiles.apache.org/framework/apidocs/) result 200).
* http://tiles.apache.org/tiles-request/apidocs/ migrated to:
  https://tiles.apache.org/tiles-request/apidocs/ ([https](https://tiles.apache.org/tiles-request/apidocs/) result 200).
* http://www.apache.org/licenses/LICENSE-2.0.txt migrated to:
  https://www.apache.org/licenses/LICENSE-2.0.txt ([https](https://www.apache.org/licenses/LICENSE-2.0.txt) result 200).
* http://www.eclipse.org/aspectj/doc/released/aspectj5rt-api/ migrated to:
  https://www.eclipse.org/aspectj/doc/released/aspectj5rt-api/ ([https](https://www.eclipse.org/aspectj/doc/released/aspectj5rt-api/) result 200).
* http://ehcache.org/apidocs/ (301) migrated to:
  https://www.ehcache.org/apidocs/ ([https](https://ehcache.org/apidocs/) result 200).
* http://static.springframework.org/spring-framework/docs (301) migrated to:
  https://docs.spring.io/spring-framework/docs ([https](https://static.springframework.org/spring-framework/docs) result 301).
* http://fasterxml.github.com/jackson-core/javadoc/2.3.0/ migrated to:
  https://fasterxml.github.com/jackson-core/javadoc/2.3.0/ ([https](https://fasterxml.github.com/jackson-core/javadoc/2.3.0/) result 301).
* http://fasterxml.github.com/jackson-databind/javadoc/2.3.0/ migrated to:
  https://fasterxml.github.com/jackson-databind/javadoc/2.3.0/ ([https](https://fasterxml.github.com/jackson-databind/javadoc/2.3.0/) result 301).
* http://glassfish.java.net/nonav/docs/v3/api/ migrated to:
  https://glassfish.java.net/nonav/docs/v3/api/ ([https](https://glassfish.java.net/nonav/docs/v3/api/) result 301).
* http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs migrated to:
  https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs ([https](https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs) result 301).
* http://pic.dhe.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.javadoc.doc/web/apidocs/ migrated to:
  https://pic.dhe.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.javadoc.doc/web/apidocs/ ([https](https://pic.dhe.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.javadoc.doc/web/apidocs/) result 301).
* http://projects.spring.io/spring-framework migrated to:
  https://projects.spring.io/spring-framework ([https](https://projects.spring.io/spring-framework) result 301).
* http://springframework.org/schema migrated to:
  https://springframework.org/schema ([https](https://springframework.org/schema) result 301).
* http://spring.io/tools/sts/all migrated to:
  https://spring.io/tools/sts/all ([https](https://spring.io/tools/sts/all) result 302).
2019-03-05 21:55:52 -06:00
Rossen Stoyanchev b8a133d2f4 Remove section on spring-framework-contrib group 2016-04-08 15:44:51 -04:00
Sam Brannen f2e5e5aa86 Eclipse project deps come after third-party libs
This commit is a backport of SPR-11836.

Prior to this commit, the ordering of classpath entries in the
generated Eclipse .classpath files did not align with the intended
dependency management configured in the Gradle build. Specifically,
project dependencies often came before dependencies on third-party
libraries required for the given project, causing the project not to
compile in Eclipse.

This commit fixes this issue by introducing new functionality in the
ide.gradle script that moves all project dependencies to the end of the
generated classpath.

Issue: SPR-12947, SPR-11836
2015-04-24 21:39:57 +02:00
Spring Buildmaster b6083c7f77 Next Development Version 2014-12-30 07:16:48 -08:00
Juergen Hoeller 8575533081 Latest dependency updates (SLF4J 1.7.9, JRuby 1.7.17, Reactor 1.1.5) 2014-12-30 13:23:46 +01:00
Juergen Hoeller 5528c8a93b Polishing 2014-12-30 13:11:46 +01:00
Juergen Hoeller c9912f0d2d Polishing
Issue: SPR-12502
(cherry picked from commit 26845f6)
2014-12-30 10:09:00 +01:00
Juergen Hoeller 8e14a5d640 Prevent NPE in AbstractApplicationEventMulticaster's non-caching code path
Issue: SPR-12545
(cherry picked from commit 1cefeb2)
2014-12-30 10:08:42 +01:00
Juergen Hoeller 230aa07fbb Polishing 2014-12-29 20:15:54 +01:00
Juergen Hoeller b9aa471def TimeZone and ZoneId as supported arguments for MVC handler methods
Issue: SPR-12575
(cherry picked from commit 3791e7f)
2014-12-29 19:03:15 +01:00
Juergen Hoeller 39fbfbd343 Doc: base-packages can be comma/semicolon/space/tab/linefeed-separated
Issue: SPR-12523
(cherry picked from commit 6f2de28)
2014-12-29 19:02:24 +01:00
Juergen Hoeller e9d24d5336 Polishing
(cherry picked from commit 86b8112)
2014-12-29 18:59:17 +01:00
Juergen Hoeller 4a27a98702 Spring's JMX support can rely on native MXBean detection on Java 6+
Issue: SPR-12574
(cherry picked from commit 0919a15)
2014-12-29 18:59:07 +01:00
Juergen Hoeller 929c596b55 AnnotationJmxAttributeSource uses AnnotationUtils for consistent meta-annotation handling and diagnostics
Issue: SPR-12572
(cherry picked from commit d4a5059)
2014-12-29 18:59:00 +01:00
Juergen Hoeller 9362d0d547 PayloadArgumentResolver does not insist on configured Validator anymore
Issue: SPR-12567
(cherry picked from commit ed0e2f4)
2014-12-29 18:58:50 +01:00
Juergen Hoeller 37713ae9dd HandlerExecutionChain prevents re-adding the interceptors array to the list (and declares varargs now)
Issue: SPR-12566
(cherry picked from commit 6b3023c)
2014-12-29 18:58:41 +01:00
Juergen Hoeller e118086bd1 Annotation post-processors clear old InjectionMetadata registrations on refresh
Issue: SPR-12526
(cherry picked from commit 809ee0d)
2014-12-29 18:56:44 +01:00
Stephane Nicoll 0c7fa9e786 Fix scope inheritance documentation
Issue: SPR-12570
2014-12-29 10:55:01 +01:00
Juergen Hoeller dc15070877 Consistent bridge method handling in annotation post-processors
Issue: SPR-12495
2014-12-22 16:42:47 +01:00
Juergen Hoeller 61a6bc0139 AbstractApplicationEventMulticaster populates ListenerRetriever cache in fully synchronized fashion
Issue: SPR-12545
(cherry picked from commit 2b0ada9)
2014-12-22 16:39:25 +01:00
Juergen Hoeller c087e51b80 AbstractFallbackTransactionAttributeSource's DefaultCacheKey takes targetClass into account (again)
Issue: SPR-12536
(cherry picked from commit 4efe6a8)
2014-12-22 16:26:25 +01:00
Rossen Stoyanchev 9cb1569e67 Synchronize message sending
Issue: SPR-12516
(backport for commit b796c1)
2014-12-08 12:02:19 -05:00
Rossen Stoyanchev ac5c361688 Check the user of a SockJS request
Issue: SPR-12497
(backport of commit dc5b5c)
2014-12-08 11:22:45 -05:00
Juergen Hoeller 328ba7b6d4 Polishing 2014-12-07 23:24:38 +01:00
Juergen Hoeller d97add075a Consistent bridge method handling in annotation post-processors
Issue: SPR-12495
(cherry picked from commit 03d4e1b)
2014-12-07 23:24:02 +01:00
Juergen Hoeller c8ff562d1f DefaultSingletonBeanRegistry's isDependent defensively checks for circular recursion
Issue: SPR-10787
(cherry picked from commit 15d3b88)
2014-12-07 22:21:55 +01:00
Juergen Hoeller 1d6978afd5 Revised ControllerAdvice basePackages handling (based on package names instead of java.lang.Package)
Issue: SPR-12506
(cherry picked from commit 4013fe0)
2014-12-07 22:20:32 +01:00
Juergen Hoeller 4660e61cf9 Consistent resolution of Class methods and static methods
Issue: SPR-12502
(cherry picked from commit 9ef0bdc)
2014-12-07 22:13:13 +01:00
Juergen Hoeller dfc79721cb AnnotationAttributesReadingVisitor defensively handles meta-annotation retrieval failure
Issue: SPR-12493
(cherry picked from commit 5018889)
2014-12-07 22:13:08 +01:00
Juergen Hoeller 90ae073854 Relaxed final declarations and protected doInvoke methods
Issue: SPR-12484
(cherry picked from commit 2496d68)
2014-12-07 22:13:03 +01:00
Juergen Hoeller 50c578c5a0 Polishing 2014-11-28 20:59:35 +01:00
Juergen Hoeller c89d8ec382 Polishing
Issue: SPR-12476
(cherry picked from commit 3b15849)
2014-11-27 20:56:41 +01:00
Juergen Hoeller 7e07f3d083 Polishing 2014-11-27 18:28:16 +01:00
Juergen Hoeller e039185fec Revised SqlRowSet javadoc
Issue: SPR-12476
(cherry picked from commit a6a837b)
2014-11-27 18:01:19 +01:00
Juergen Hoeller b45f1aa26f ExtendedBeanInfo ignores invalid bean properties (analogous to the JavaBeans Introspector)
Issue: SPR-12434
(cherry picked from commit eacd4a1)
2014-11-27 01:48:33 +01:00
Juergen Hoeller 054464709f Latest dependency updates (Tomcat 8.0.15, JRuby 1.7.16.1) 2014-11-26 16:07:21 +01:00
Juergen Hoeller 5ac868036f Clarified getAllAnnotationAttributes behavior
Issue: SPR-12473
2014-11-26 15:35:24 +01:00
Juergen Hoeller 58bea23f1d NotReadablePropertyException accepts root cause (analogous to NotWritablePropertyException)
Issue: SPR-12467
(cherry picked from commit feb91e8)
2014-11-26 12:11:40 +01:00
Juergen Hoeller 98569045cb Tracking ASM 5.0.4 development: Fix for ASM issue 317545
Issue: SPR-12470
(cherry picked from commit ab5856b)
2014-11-26 12:11:13 +01:00
Stephane Nicoll c2ffbf28c5 Fix typo 2014-11-24 21:01:53 +01:00
Stephane Nicoll a5e2afc980 Fix documentation formatting
Using the "quotes" substitution group by default leads to side effect
when the "*" character is used. This is especially true for AOP pointcut
or for MVC mappings.

Plain verbatim might work most of the time unless you intend to highlight
a piece of code or a comment.

Issue: SPR-12456
(cherry picked from commit 0d00b674f4)
2014-11-24 21:01:53 +01:00
Juergen Hoeller 5be50c8e5e Polishing
Issue: SPR-12462
2014-11-24 17:41:43 +01:00
Brian Clozel 1214624265 Fix location checks for servlet 3 resources
SPR-12354 applied new checks to make sure that served static resources
are under authorized locations.

Prior to this change, serving static resources from Servlet 3 locations
such as "/webjars/" would not work since those locations can be within
one of the JARs on path. In that case, the checkLocation method would
return false and disallow serving that static resource.

This change fixes this issue by making sure to call the
`ServletContextResource.getPath()` method for servlet context resources.

Note that there's a known workaround for this issue, which is using a
classpath scheme as location, such as:
"classpath:/META-INF/resources/webjars/" instead of "/webjars".

Issue: SPR-12432
(cherry picked from commit 161d3e3)
2014-11-24 17:41:11 +01:00
Brian Clozel 493e8463fa Use https for maven repositories
(cherry picked from commit 44ff143)
2014-11-23 00:07:51 +01:00
Juergen Hoeller 6d3a0d5735 Polishing 2014-11-23 00:05:27 +01:00
Juergen Hoeller 5f58cd3b79 Polishing
(cherry picked from commit 2675ce7)
2014-11-22 22:47:24 +01:00
Juergen Hoeller 8854c33bf7 Rearranged WebAsyncTask constructor interdependencies and assertions
Issue: SPR-12457
(cherry picked from commit aadb93f)
2014-11-22 22:45:24 +01:00
Juergen Hoeller f093a5f749 RequestMappingHandlerAdapter allows for overriding handleInternal
Issue: SPR-12460
(cherry picked from commit ece2c90)
2014-11-22 22:45:19 +01:00
Juergen Hoeller 1f45dd297d Unit test for JavaBeans introspection against FreeMarker Configuration class
Issue: SPR-12448
(cherry picked from commit 282aded)
2014-11-22 22:45:12 +01:00
Juergen Hoeller 21b8ce5284 MethodParameter generally uses volatile variables where applicable now (as well as a local copy of the parameterNameDiscoverer field)
Issue: SPR-12453
(cherry picked from commit 7fcadaa)
2014-11-22 22:44:38 +01:00
Juergen Hoeller 2490d1b38d MutablePropertySources uses an internal CopyOnWriteArrayList for defensiveness against concurrent modifications
Issue: SPR-12428
(cherry picked from commit 1ef06cc)
2014-11-22 22:44:30 +01:00
Spring Buildmaster ffa4736895 Next Development Version 2014-11-10 22:50:00 -08:00
Rossen Stoyanchev 9beae9ae42 Apply extra checks to static resource handling
- remove leading '/' and control chars
- improve url and relative path checks
- account for URL encoding
- add isResourceUnderLocation final verification

Issue: SPR-12354
2014-11-11 06:31:57 +01:00
Juergen Hoeller e42e2330b3 Polishing 2014-11-11 03:21:43 +01:00
Sebastien Deleuze b331d65019 Check STOMP headers against ending backslash
Issue: SPR-12418
(cherry picked from commit 1803348)
2014-11-11 03:02:25 +01:00
Juergen Hoeller 1823ce1fad ShallowEtagHeaderFilter skips "Cache-Control" header check on Servlet 2.5
Issue: SPR-12414
(cherry picked from commit bf9295b)
2014-11-06 23:19:33 +01:00
Rossen Stoyanchev 2d0a677117 Improve exception message
Issue: SPR-12230
(cherry picked from commit 7f4bf41)
2014-11-06 16:15:04 +01:00
Sam Brannen a09bc9b1c1 Log context cache statistics in the TCF
Prior to this commit, finding out how many application contexts had
been loaded within a test suite required the use of reflection and a
bit of hacking.

This commit addresses this issue by logging ContextCache statistics
whenever an application context is loaded by the Spring TestContext
Framework (TCF).

The log output can be enabled by setting the
"org.springframework.test.context.cache" logging category to DEBUG.

Issue: SPR-12409
(cherry picked from commit da04362)
2014-11-06 16:13:37 +01:00
Stephane Nicoll 260b451d5f Add documentation for the keep-alive flag
This commit updates the documentation of the task:executor element to
reference the keep-alive flag.

Issue: SPR-12407
(cherry picked from commit 6534d00)
2014-11-06 15:28:38 +01:00
Juergen Hoeller acefd8381d Polishing 2014-11-02 11:38:35 +01:00
Juergen Hoeller 7fa3e65d04 Test for cyclic type declaration handling in TypeDescriptor
Issue: SPR-9735
2014-11-02 11:38:28 +01:00
Juergen Hoeller 329ba2a913 Removed outdated TimerTaskExecutor reference (and other minor doc updates)
Issue: SPR-12389
2014-11-01 13:02:36 +01:00
Juergen Hoeller f691618967 Polishing 2014-11-01 13:00:54 +01:00
Juergen Hoeller fde0713a94 Upgrade to Hibernate 4.2.16 (and AspectJ 1.8.3) 2014-11-01 13:00:39 +01:00
Juergen Hoeller 4729483804 HibernateJpaSessionFactoryBean is compatible with Hibernate 4.3 as well now
Issue: SPR-12401
(cherry picked from commit bf5739c)
2014-11-01 12:59:15 +01:00
Juergen Hoeller d3ec48f490 PersistenceAnnotationBeanPostProcessor correctly detects JPA 2.1 synchronization attribute
Issue: SPR-12396
(cherry picked from commit a181b40)
2014-11-01 12:58:38 +01:00
Juergen Hoeller 2d874d724b SimpleMetadataReaderFactory is capable of resolving inner class names with dot syntax now (analogous to ClassUtils.forName)
Issue: SPR-12390
(cherry picked from commit 725ad0d)
2014-11-01 12:58:08 +01:00
Juergen Hoeller 91940f212e Normalized AnnotationAttributesReadingVisitor class layout and improved diagnostics through delegating to AnnotationUtils
Issue: SPR-12387
(cherry picked from commit b70c5d1)
2014-11-01 12:57:10 +01:00
Juergen Hoeller de8645b30c Test for <util:map> with LinkedCaseInsensitiveMap and specified key/value types
Issue: SPR-10994
(cherry picked from commit 9243869)
2014-11-01 12:56:24 +01:00
Juergen Hoeller c8b8dc5f97 TilesConfigurer defensively expects null from getResources in case of no resources found
Also includes order preservation for resource results with Tiles 2 as well as retrieval failure logging with Tiles 3.

Issue: SPR-12362
(cherry picked from commit cb86036)
2014-11-01 12:55:53 +01:00
Juergen Hoeller aa82da8507 Set ResponseStatusExceptionResolver.messageSource in the MVC Java config
Issue: SPR-12380
(cherry picked from commit 17b9bde)
2014-11-01 12:55:03 +01:00
Juergen Hoeller 16a4fe70f2 Polishing
(cherry picked from commit 2956049)
2014-10-22 17:14:23 +02:00
Juergen Hoeller 6117311906 QualifierAnnotationAutowireCandidateResolver calls BeanFactory.getType defensively
Issue: SPR-12191
(cherry picked from commit 73ce3b5)
2014-10-22 17:14:02 +02:00
Juergen Hoeller 6e5711a7fb Revised test for ImportBeanDefinitionRegistrar double scan
Issue: SPR-12334
2014-10-22 02:16:39 +02:00
Juergen Hoeller 15c8987cc4 Polishing 2014-10-22 01:10:01 +02:00
Juergen Hoeller 0e907764a4 Test for ImportBeanDefinitionRegistrar double scan
Issue: SPR-12334
(cherry picked from commit 38030ef)
2014-10-22 01:09:47 +02:00
Juergen Hoeller a305bf7ad1 Latest dependency updates (Hibernate 4.2.15, Tiles 3.0.5) 2014-10-22 01:09:31 +02:00
Juergen Hoeller e16f21c281 AnnotationUtils consistently logs introspection failures via lazily initialized logger
Issue: SPR-12325
Issue: SPR-12329
2014-10-22 01:08:41 +02:00
Juergen Hoeller 7507560e75 Reimplemented ServerEndpointExporter to avoid BeanPostProcessor role
Issue: SPR-12340
(cherry picked from commit 10328f1)
2014-10-22 01:05:19 +02:00
Juergen Hoeller a1c0905a7c Consistently accept empty Content-Type header and empty character encoding
Issue: SPR-12173
(cherry picked from commit d501137)
2014-10-22 01:04:22 +02:00
Juergen Hoeller 6f9d7da59e Consistent use of LinkedHashSet for interfaces (since interface order may matter in subtle cases)
(cherry picked from commit 5a63117)
2014-10-07 17:26:48 +02:00
Juergen Hoeller 47ed4d634b Explicitly detect (and log) private @Scheduled methods on CGLIB proxies
Issue: SPR-12308
(cherry picked from commit 01724d3)
2014-10-07 17:26:35 +02:00
Juergen Hoeller da2c30cd0c TextMessage.toString() does not throw StringIndexOutOfBoundsException for payload with multibyte characters
Issue: SPR-12307
(cherry picked from commit da14aee)
2014-10-07 17:15:23 +02:00
Juergen Hoeller a7eeedaf6a Fix outdated references to JobDetailBean
Issue: SPR-12306
(cherry picked from commit aaf69eb)
2014-10-07 17:13:53 +02:00
Juergen Hoeller 578c3dd853 Polishing
(cherry picked from commit d6be433)
2014-10-07 00:53:01 +02:00
Juergen Hoeller 9758bc7833 Consistent reset of resource holders on doBegin failure
Issue: SPR-12280
(cherry picked from commit e58b33a)
2014-10-07 00:06:49 +02:00
Juergen Hoeller c672678423 Provider declaration for @Value method argument works again
Issue: SPR-12297
(cherry picked from commit 70fec47)
2014-10-07 00:02:03 +02:00
Juergen Hoeller ac4103d1b9 Further locking optimizations for the retrieval of non-singleton beans
Issue: SPR-12250
(cherry picked from commit 9d83281)
2014-10-07 00:01:40 +02:00
Juergen Hoeller d23b033f61 Polishing 2014-10-01 01:20:01 +02:00
Juergen Hoeller c74bad6e07 Remove outdated references to ContextLoaderServlet
Issue: SPR-7725
(cherry picked from commit 69998e3)
2014-10-01 01:14:57 +02:00
Juergen Hoeller f41e0bc796 Latest dependency updates (POI 3.10.1, JRuby 1.7.16) 2014-09-30 20:27:19 +02:00
Stephane Nicoll c7b6b72e73 Optimize ResolvableType cache
Prior to this commit, the ResolvableType static cache was holding a lot
of duplicates for simple types. We are using too much metadata to compute
the key when the class has no generic information. so setFoo(String foo)
and setBar(String bar) would result in two entries in the cache because
the TypeProvider is different. On a very simple application 65% of the
entries in the cache were duplicate.

When the type is a Class with no generic information, the ResolvableType
instance is a simple wrapper around it so we might just as well not cache
it at all as the cost of finding it back from the cache is higher than
creating that simple wrapper.

This commit adds an explicit check; if the type is a simple Class we just
return a "resolved" ResolvableType instance for it. On a few test cases,
this reduces the size of the cache by 85%

Issue: SPR-12275
(cherry picked from commit 6f1acdd)
2014-09-30 20:22:51 +02:00
Anders D. Johnson 1df8133237 Fix condition vs. conditional typo in documenation
Issue: SPR-12273
(cherry picked from commit bc0e59f)
2014-09-30 09:53:21 +02:00
Juergen Hoeller 43d40187d9 Polishing 2014-09-29 23:40:32 +02:00
Juergen Hoeller b91cab1fde Polishing 2014-09-26 22:18:15 +02:00
Juergen Hoeller d46c3fc7bf Deprecated BeanDefinitionDocumentReader's setEnvironment method in favor of access via XmlReaderContext
Issue: SPR-12248
2014-09-26 22:17:58 +02:00
Brian Clozel 3267e5aa33 Update default SockJS CDN location
This commit updates the default location of the SockJS' client library.
The previous location is being retired by the project maintainers.

The new default location is backed by several CDN providers:
* https://cdn.jsdelivr.net/sockjs/0.3.4/sockjs.min.js

See sockjs/sockjs-client#198

Issue: SPR-12254
(cherry picked from commit a6e1c53)
2014-09-26 22:17:04 +02:00
Juergen Hoeller 251970a2f9 Tracking ASM 5.0.4 development: Fix for ASM issue 317539
Issue: SPR-12255
(cherry picked from commit e8486e2)
2014-09-26 21:47:41 +02:00
Juergen Hoeller 901346eb7d WebAsyncManager avoids concurrentResult.toString() and builds correct DeferredResultProcessingInterceptor keys
Issue: SPR-12253
(cherry picked from commit bf99d6a)
2014-09-26 21:47:30 +02:00
Juergen Hoeller 1ffefcb548 LiveBeansView escapes double quotes in resource descriptions
Issue: SPR-12252
(cherry picked from commit 92f7121)
2014-09-26 21:47:21 +02:00
Juergen Hoeller 0c680d6d03 Defensively use setRemoveOnCancelPolicy for JDK 6 compatibility
Issue: SPR-12238
(cherry picked from commit e003d21)
2014-09-26 21:47:01 +02:00
Juergen Hoeller b87329cda7 Remove outdated references to ContextLoaderServlet
Issue: SPR-7725
(cherry picked from commit 94e26fd)
2014-09-26 21:40:28 +02:00
Juergen Hoeller f21c8c37fb Avoid use of fragile Swing classes in tests (for compatibility with JDK 8u40)
Issue: SPR-12235
(cherry picked from commit a80495b)
2014-09-26 21:40:09 +02:00
Juergen Hoeller 50e50d0c18 Polishing
(cherry picked from commit 16325c2)
2014-09-20 00:51:19 +02:00
Juergen Hoeller 205e681295 Backported tests for property source ordering
Issue: SPR-12198
(cherry picked from commit 90b93ff)
2014-09-19 00:20:00 +02:00
Juergen Hoeller 29abca5399 Explicit exclusion of bridge methods in annotation post-processors (for Java 8 compatibility)
Issue: SPR-12187
(cherry picked from commit f4219ca)
2014-09-19 00:11:44 +02:00
Juergen Hoeller 60d5ff8dd5 Polishing
(cherry picked from commit a833889)
2014-09-17 22:10:08 +02:00
Juergen Hoeller d2e8b7e6ee ScheduledAnnotationBeanPostProcessor avoids needless re-scanning of non-annotated classes
Issue: SPR-12189
(cherry picked from commit 58b22ce)
2014-09-17 22:09:43 +02:00
Juergen Hoeller 7d55715213 Polishing 2014-09-17 13:53:12 +02:00
Juergen Hoeller d07230cf6a BeanDefinitionParserDelegate does not silently ignore 1.x 'singleton' attribute
Issue: SPR-12167
(cherry picked from commit 0cf472b)
2014-09-17 13:36:54 +02:00
Juergen Hoeller bf881e4544 Log warning for single optional constructor when no default constructor to fall back to
Issue: SPR-12161
(cherry picked from commit 80cec01)
2014-09-17 13:35:12 +02:00
Juergen Hoeller 36a1d6242e Latest dependency updates (Reactor 1.1.4) 2014-09-17 02:39:16 +02:00
Juergen Hoeller 10d4888408 Polishing 2014-09-17 02:37:32 +02:00
Juergen Hoeller f8b729aa5f Polishing 2014-09-17 01:51:23 +02:00
Juergen Hoeller b39e66b897 GenericTypeAwarePropertyDescriptor implements equals/hashCode for proper lookups on IBM JVM 6
Issue: SPR-12185
2014-09-17 01:42:30 +02:00
Juergen Hoeller 64849a46b4 Client request implementations enforce RFC 6265 (cookies in a single header)
Issue: SPR-12196
(cherry picked from commit 26a93b6)
2014-09-17 00:44:30 +02:00
Juergen Hoeller afb0342924 Accept empty Content-Type header
Issue: SPR-12173
(cherry picked from commit 70412a9)
2014-09-17 00:37:38 +02:00
Sam Brannen bea9f3ff76 Make SocketUtils a concrete class
Per the Javadoc for the SocketUtils() constructor, SocketUtils can be
instantiated as a Spring Bean in XML configuration files; however,
SocketUtils is currently abstract which prevents such usage.

This commit removes the 'abstract' declaration thereby allowing
SocketUtils to be instantiated as a Spring bean.

Issue: SPR-12169
(cherry picked from commit 559e81b)
2014-09-17 00:36:21 +02:00
Spring Buildmaster 31094f3ef6 Next Development Version 2014-09-04 01:18:19 -07:00
Juergen Hoeller d765698ac3 Polishing 2014-09-04 03:06:37 +02:00
Juergen Hoeller d081a4530c Polishing 2014-09-04 02:37:36 +02:00
Juergen Hoeller 97bd0ccfec Polishing 2014-09-04 01:43:15 +02:00
Juergen Hoeller 8543a5548e CachingConnectionFactory proceeds to physicalClose in case of logicalClose exceptions
Issue: SPR-12148
(cherry picked from commit 82f8b43)
2014-09-04 00:58:50 +02:00
Juergen Hoeller d2ef6dcb8d Polishing 2014-09-03 13:49:37 +02:00
Juergen Hoeller bff2bf2cdb AbstractAutowireCapableBeanFactory avoids early FactoryBean instantiation on currently created configuration bean
Issue: SPR-12141
(cherry picked from commit 4432c41)
2014-09-03 13:48:47 +02:00
Juergen Hoeller 72d62a7113 Cache.get(key, type) explicitly defines an IllegalStateException in case of a type mismatch
Issue: SPR-12145
(cherry picked from commit 2f93759)
2014-09-03 13:48:19 +02:00
Stephane Nicoll e1a01d4c3c Improve configuration changes in GuavaCacheManager
Prior to this commit, setting the parameters used to build the caches
was fragile in static mode as the caches were created right when the
setCacheNames setter was called.

This commit provides a better handling of such arguments and also
provide a way to restore the dynamic mode if necessary.

Issue: SPR-12120
(cherry picked from commit d47c543)
2014-09-01 14:08:14 +02:00
Sebastien Deleuze b7726ff48c Improve ResolvableType.hashCode() for better performance
Prior to this commit, when there was a lot of entries in the
ResolvableType.cache HashMap, getting a simple value could
take a lot of time due to a lot of calls to ResolvableType.equals().
ResolvableType.equals() used this.type, getSource(),
this.variableResolver.getSource() and this.componentType, but
ResolvableType.hashCode() used only this.type.

With this commit, ResolvableType.hashCode() now uses the same
fields than ResolvableType.equals().

Performance on the spring-resolvabletype-benchmark project:
 - 8000 us before this commit
 - 120 us with this commit

Issue: SPR-12122
(cherry picked from commit 7ea69fb)
2014-09-01 14:07:43 +02:00
Sam Brannen a52ff46fea Include ALL source artifacts in published sources jars
This commit updates the Gradle build to ensure that *all* source
artifacts are including in published 'sources' jars.

To achieve this, we are now assembling 'sources' jars from
'sourceSets.main.allSource' and not explicitly including or excluding
anything by default.

Issue: SPR-12085
(cherry picked from commit 07629a3c7c)
2014-08-26 16:51:26 +02:00
Juergen Hoeller eb3509a37c Polishing 2014-08-23 02:02:38 +02:00
Juergen Hoeller 93ad7f8def Polishing 2014-08-23 01:28:10 +02:00
Juergen Hoeller 54ba5c5e7b Polishing 2014-08-22 23:39:37 +02:00
Juergen Hoeller 249c688e9b DispatcherServlet's checkMultipart detects wrapped MultipartRequest as well
Issue: SPR-12114
(cherry picked from commit 786fd92)
2014-08-22 23:18:39 +02:00
Juergen Hoeller e324c2ab4a Polishing 2014-08-22 00:14:10 +02:00
Juergen Hoeller 39a23660fa PropertySource implementations perform conversion to String arrays via StringUtils (getting rid of EMPTY_NAMES_ARRAY)
(cherry picked from commit b73c531)
2014-08-22 00:09:53 +02:00
Juergen Hoeller 25971d9927 Consistent attribute documentation/formatting in spring-context and spring-mvc schemas
(cherry picked from commit b5763fe)
2014-08-22 00:04:12 +02:00
Juergen Hoeller 379e5abd83 ServerEndpointExporter can initialize itself based on a late-provided ServletContext as well (for Boot)
Also allows for direct setting of a ServerContainer and for custom triggering of endpoint registration.

Issue: SPR-12109
(cherry picked from commit 11805b6)
2014-08-22 00:02:14 +02:00
Juergen Hoeller 8fb7b694dd PersistenceAnnotationBeanPostProcessor defensively handles BeanDefinition access for extended EntityManagers
Issue: SPR-8834
(cherry picked from commit 592e344)
2014-08-22 00:01:39 +02:00
Juergen Hoeller 21d0ce5af8 DefaultListableBeanFactory defensively handles BeanDefinition access in getBean(Class)
Issue: SPR-10542
(cherry picked from commit 9d3d6d5)
2014-08-22 00:01:16 +02:00
Juergen Hoeller fb452fad7c Upgrade to Apache HttpComponents HttpClient 4.3.5 and HttpAsyncClient 4.0.2
Issue: SPR-12100
(cherry picked from commit 5cd1e6a)
2014-08-19 21:41:57 +02:00
Juergen Hoeller 2dd2b7175f ShallowEtagHeaderFilter supports Servlet 3.1's setContentLengthLong as well
Issue: SPR-12097
(cherry picked from commit 0c32d66)
2014-08-19 21:39:43 +02:00
Juergen Hoeller f418e6e981 Polishing 2014-08-18 22:24:43 +02:00
Juergen Hoeller 5e2b9b6f07 Latest dependency updates (AspectJ 1.8.2, Jackson 2.3.4) 2014-08-18 22:19:33 +02:00
Stephane Nicoll a95a3ae4ec Exclude infra modules from public distribution
Prior to this commit, spring-build-src and spring-framework-bom
internal artifacts were published as part of the distribution bundle.

This commit excludes those projects so that those unnecessary artifacts
are no longer shipped.

Issue: SPR-12087
2014-08-18 12:20:24 +02:00
Juergen Hoeller 0c0d23d0f4 Polishing 2014-08-15 00:58:05 +02:00
Juergen Hoeller a31ebb6c1e Polishing 2014-08-15 00:07:25 +02:00
Juergen Hoeller 42c090efa4 Polishing
Issue: SPR-12079
(cherry picked from commit 92bd240)
2014-08-13 15:28:36 +02:00
Juergen Hoeller 035a9b91d2 BeanNameViewResolver ignores non-View beans
Issue: SPR-12079
(cherry picked from commit 626a5fe)
2014-08-13 15:28:09 +02:00
Juergen Hoeller a7492fa55b Polishing 2014-08-12 22:24:50 +02:00
Juergen Hoeller ecf23ff6cd Remove outdated IDE, JIRA and Tomcat references
Issue: SPR-7521
(cherry picked from commit f1f1c4c)
2014-08-12 22:11:49 +02:00
Juergen Hoeller 4129f00a02 Polishing
(cherry picked from commit 4db258b)
2014-08-11 22:35:26 +02:00
Juergen Hoeller e2d71a8ccd Polishing 2014-08-11 15:45:54 +02:00
Juergen Hoeller 1034b0dae2 Tiles 3 TilesViewResolver allows for specifying custom TilesView subclasses as well
Issue: SPR-12075
(cherry picked from commit 7c57424)
2014-08-11 15:45:14 +02:00
Juergen Hoeller c08ded769a Polishing (includes varargs for selected String array setters) 2014-08-09 00:19:56 +02:00
Juergen Hoeller d61353db51 AnnotatedElementUtils adapts post-processed values to AnnotationAttributes as well
Issue: SPR-12065
(cherry picked from commit ef51d4d)
2014-08-09 00:19:28 +02:00
Rossen Stoyanchev 96efafef97 Fix documentation issue for user destinations.
Issue: SPR-11992
2014-07-31 17:15:52 -04:00
Rossen Stoyanchev fbf24a927d Update Javadoc (cherry-picked from 162734)
Issue: SPR-12028
2014-07-29 18:07:36 -04:00
Juergen Hoeller f2eea9d911 Polishing
(cherry picked from commit 8f484d3)
2014-07-29 11:50:50 +02:00
Juergen Hoeller cac0683dab Rearranged statement whitespace in Velocity macros
(cherry picked from commit 7bc9660)
2014-07-29 11:47:12 +02:00
Juergen Hoeller 9ad6618207 Polishing 2014-07-28 22:47:22 +02:00
Juergen Hoeller 84a4433898 AbstractTypeHierarchyTraversingFilter leniently ignores non-loadable super classes and interfaces
Issue: SPR-12042
(cherry picked from commit a3163ce)
2014-07-28 22:27:37 +02:00
Juergen Hoeller 44fac40a2f Latest dependency updates (Hibernate Validator 4.3.2, propdeps plugin 0.0.7) 2014-07-28 22:27:28 +02:00
Juergen Hoeller 6e95b2613e Polishing 2014-07-24 18:35:49 +02:00
Arjen Poutsma fca72f6b65 StaxStreamXMLReader ignores significant whitespace
The StaxStreamXMLReader no longer handles all whitespace as ignorable
whitespace.

Issue: SPR-12000
(cherry picked from commit d6950d8)
2014-07-24 17:57:14 +02:00
Juergen Hoeller 0dca31c39b Typo fixes and cleanup of outdated Java 5 references
Issue: SPR-12020
(cherry picked from commit d4fe732)
2014-07-24 17:56:35 +02:00
Juergen Hoeller d45f743248 TypeDescriptor's getResolvableType() and getSource() are @since 4.0
(cherry picked from commit 0ce90f1)
2014-07-24 17:55:39 +02:00
Juergen Hoeller acbd61b87a ConcurrentMapCacheManager recreates caches in case of setAllowNullValues change
Issue: SPR-12026
(cherry picked from commit 7848412)
2014-07-24 17:54:22 +02:00
Juergen Hoeller dcb83c2daf Autowiring rejects self references to a factory method on the same bean as well
Issue: SPR-12018
(cherry picked from commit 496492b)
2014-07-24 17:53:21 +02:00
Juergen Hoeller 5342d92db7 ResourceHttpMessageConverter does not call contentLength() on InputStreamResource
Issue: SPR-12017
(cherry picked from commit f0bcb77)
2014-07-24 17:50:31 +02:00
Juergen Hoeller 7af1e002bd AbstractMessageListenerContainer calls "Session.recover()" in case of rollback attempt on non-transacted Session
Issue: SPR-12015
(cherry picked from commit c082220)
2014-07-24 17:49:34 +02:00
Juergen Hoeller abd5f18e85 AbstractApplicationContext logs initialization exception before trying to cancel refresh attempt
Issue: SPR-12010
(cherry picked from commit 5e2fbe7)
2014-07-24 17:48:08 +02:00
Juergen Hoeller 940ae0c528 ClassUtils.isCacheSafe defensively catches SecurityException (for Google App Engine compatibility)
Issue: SPR-12002
(cherry picked from commit 48fea0b)
2014-07-24 17:46:42 +02:00
Juergen Hoeller 5f77dce1ee SelectedValueComparator defensively handles null values in exhaustiveCompare
Issue: SPR-12001
(cherry picked from commit 980f971)
2014-07-24 17:46:04 +02:00
Juergen Hoeller 0ef17a2f2c NestedIOException can use IOException constructor with cause argument on JDK 6+
(cherry picked from commit c18b6bf)
2014-07-24 17:44:57 +02:00
Juergen Hoeller 452260316e DefaultListableBeanFactory's registerBeanDefinition only calls resetBeanDefinition in case of pre-existing bean definition or pre-existing singleton instance
Issue: SPR-8318
(cherry picked from commit a4968b9)
2014-07-24 17:43:59 +02:00
Stephane Nicoll c0815407bb Revert ea16ce0
The latest build preview of jdk 1.8.0_20 does not exhibit the problem
anymore.

Issue: SPR-11973
2014-07-23 19:43:09 +02:00
Juergen Hoeller 845528a6cb Polishing 2014-07-10 18:18:44 +02:00
Juergen Hoeller ed88155f55 Reverted test for 1.8 bytecode parsing - 4.0.x tests are still on target 1.7
Issue: SPR-11979
2014-07-10 17:45:08 +02:00
Brian Clozel a3a76d8c15 Fix UriComponentsBuilder.fromUriString parsing error
This commit fixes cases where part of the URI was mistaken for the
userinfo when:
* the URI did not contain any path
* the query string contained the "@"

Issue: SPR-11970
(cherry picked from commit a4484bb)
2014-07-10 16:46:33 +02:00
Juergen Hoeller 10a039000b Test ASM5's bytecode parsing of INVOKESPECIAL/STATIC on interfaces
Issue: SPR-11979
(cherry picked from commit 29f6f3d)
2014-07-10 16:44:59 +02:00
Spring Buildmaster 7de42efaf2 Next development version 2014-07-07 20:49:34 -07:00
Phillip Webb 7dcc01e69b Disable processing javac warnings
Set `-Xlint:-processing` to disable annotation processing warnings.
Required when building on JDK 1.8.0_20-b05 due to JDK-8039469.

Issue: SPR-11973
(cherry picked from commit ea16ce0)
2014-07-07 19:22:07 -07:00
Juergen Hoeller adb73d5f35 Remaining polishing 2014-07-08 00:21:17 +02:00
Juergen Hoeller 7eee7d2e30 Polishing
Issue: SPR-8045
2014-07-08 00:04:19 +02:00
Juergen Hoeller d72ee809b7 Polishing
(cherry picked from commit b559f15)
2014-07-07 21:51:01 +02:00
Juergen Hoeller 31a251e44a Polishing 2014-07-07 20:53:26 +02:00
Brian Clozel ce6adfbe35 Remove Jackson dependency from TransportHandler hierarchy
Prior to this change, AbstractHttpReceivingTransportHandler had a direct
dependency on a Jacckson Exception (checking that exception in a catch
clause). This can cause issues for applications that don't have that
dependency.

This commit removes that direct dependency, still logging the
appropriate log messages using a parent exception (IOException) and
reflection.

Issue: SPR-11963
(cherry picked from commit e549103)
2014-07-07 20:39:29 +02:00
Juergen Hoeller 60d3a7f300 RestTemplate accepts getMessageConverters() List on setMessageConverters again
Issue: SPR-11962
(cherry picked from commit 1222ca3)
2014-07-07 20:37:35 +02:00
Juergen Hoeller 6dbb465585 TypedValue implements equals/hashCode based on value and TypeDescriptor
Issue: SPR-11960
(cherry picked from commit a8848cb)
2014-07-07 20:36:53 +02:00
Juergen Hoeller 47de943926 Upgraded to AspectJ 1.8.1 (also declared as recommended user version) and Tomcat 8.0.9 (first stable version)
Issue: SPR-11957
2014-07-05 11:14:34 +02:00
Juergen Hoeller 0164f8691a CachedSessionInvocationHandler includes durable flag in ConsumerCacheKey
Issue: SPR-11956
(cherry picked from commit 6fd0fc7)
2014-07-05 08:56:10 +02:00
Juergen Hoeller 077c624b73 ConstructorResolver's exception message on null factory-bean hints at potential BeanPostProcessor involvement
Issue: SPR-11951
(cherry picked from commit 6c41cc3)
2014-07-04 22:32:10 +02:00
Juergen Hoeller dae81fd5e6 CachedSessionInvocationHandler properly caches createSharedConsumer results
Issue: SPR-11956
(cherry picked from commit 7a7641b)
2014-07-04 22:31:38 +02:00
Juergen Hoeller 837f27851f Jms2MessageProducerInvocationHandler specifically delegates all CompletionListener-based send methods
Issue: SPR-11950
(cherry picked from commit b6a7957)
2014-07-04 16:13:14 +02:00
Juergen Hoeller c3b992c5c4 Jms2MessageProducerInvocationHandler properly delegates to CachedMessageProducer.this
Issue: SPR-11949
(cherry picked from commit 134e5a2)
2014-07-04 00:27:25 +02:00
Juergen Hoeller f8ab4f6980 Reference documentation backports
Issue: SPR-11944
Issue: SPR-11945
2014-07-03 22:40:02 +02:00
Juergen Hoeller 77406eded8 Refined DefaultJpaDialect's InvalidIsolationLevelException message
Issue: SPR-8325
(cherry picked from commit af13310)
2014-07-03 22:34:14 +02:00
Rossen Stoyanchev 977c5ca439 Synchronize request init in AbstractHttpSockJsSession
Although unlikely in practice (but not impossible), the SockJS
integration tests write a message while the request is initializing.
This change adds synchronization around request intiailization
for the SockJS HTTP sesion.

This is a backport of:
https://github.com/spring-projects/spring-framework/commit/59e02e63c427659e701cc371d210faf1a85c1d42

Issue: SPR-11916
2014-07-02 18:28:48 -04:00
Juergen Hoeller ede2150544 Polishing 2014-07-02 17:32:43 +02:00
Juergen Hoeller 07edf11e21 Defensively check for pre-resolved FactoryBean.getObject() results in circular reference scenarios
Issue: SPR-11937
(cherry picked from commit d870b38)
2014-07-02 00:23:32 +02:00
Juergen Hoeller f27b9498be CachedIntrospectionResults uses SoftReference instead of WeakReference for non-cache-safe entries
Issue: SPR-11867
2014-07-02 00:22:24 +02:00
Rossen Stoyanchev e9ecaf6f4a Fix issue with StompSubProtocolHandler initialization
This change ensures that StompSubProtocolHandler is injected with an
ApplicationEventPublisher for both the Java and XML config.

Backport for:
https://github.com/spring-projects/spring-framework/commit/0dddb6f3e19377cb397f0396e85734df2c19c2b6
https://github.com/spring-projects/spring-framework/commit/4372dac002be4dd9be9568fafb442cde5b6d1ada

Issue: SPR-11825
2014-07-01 14:59:51 -04:00
Rossen Stoyanchev 5092414842 Improve SubscriptionRegistry subscription removal
This a backport of:
https://github.com/spring-projects/spring-framework/commit/ce20abde51ac52dde2f318e28004af80cca886fe
https://github.com/spring-projects/spring-framework/commit/083d415fc4d54ce19f7939b3d837f1f1eda5732a

Issue: SPR-11931, SPR-11930
2014-07-01 14:35:22 -04:00
Rossen Stoyanchev 6438209557 Remove JDK 1.7 guards 2014-07-01 14:33:27 -04:00
Juergen Hoeller 7396210d40 Package javadoc cleanup for web.servlet.mvc, removing outdated references
Issue: SPR-11935
(cherry picked from commit ba522e5)
2014-07-01 18:12:42 +02:00
Juergen Hoeller b9935e9fe3 BeanFactoryAnnotationUtils consistently applies bean name fallback when no BeanDefinition present
Issue: SPR-11915
(cherry picked from commit f8b6114)
2014-07-01 18:12:23 +02:00
Juergen Hoeller 86ea3059b6 Polishing 2014-07-01 15:11:36 +02:00
Juergen Hoeller 4384c1ae50 Upgrade to Reactor 1.1.3 2014-07-01 15:10:09 +02:00
Juergen Hoeller 347b7313b8 Dependency updates (as appropriate for the 4.0.x line) 2014-07-01 12:31:47 +02:00
Juergen Hoeller 3fb05017a1 Reference documentation overhaul (backported from master)
Issue: SPR-11853
Issue: SPR-11906
2014-07-01 12:31:16 +02:00
Juergen Hoeller 48f753f368 Polishing (backported from master) 2014-07-01 12:12:42 +02:00
Juergen Hoeller c16032b98a Consistent declaration of private static final logger variables
Issue: SPR-11905
(cherry picked from commit 18131bf)
2014-07-01 12:09:29 +02:00
Juergen Hoeller c32d5592c7 AbstractAutowireCapableBeanFactory's createBean/autowireBean/configureBean use CacheUtils.isCacheSafe to re-enable PropertyDescriptor caching
Issue: SPR-11875
(cherry picked from commit 974bd43)
2014-07-01 12:07:26 +02:00
Juergen Hoeller 5f695a47db Cache Class.getDeclaredMethods() results and avoid pattern matching in isCglibRenamedMethod as far as possible
Issue: SPR-11882
Issue: SPR-11894
2014-07-01 12:06:34 +02:00
Juergen Hoeller 74c878ee0e AnnotationUtils defensively catches and logs unexpected exceptions from retrieval attempts (proceeding like the annotation wasn't there)
Issue: SPR-11874
(cherry picked from commit 2c0c081)
2014-07-01 12:05:38 +02:00
Juergen Hoeller 178d58cc75 ConfigurationClassParser falls back to ASM-based resolution of member classes in case of NoClassDefFoundError
Issue: SPR-11844
(cherry picked from commit 6aa9c40)
2014-07-01 12:02:27 +02:00
Juergen Hoeller 7b38b41bf5 ConfigurationClassPostProcessor skips pre-processed bean definitions now (avoiding side effects in case of multiple CCPPs)
Issue: SPR-11858
(cherry picked from commit b625512)
2014-07-01 12:01:50 +02:00
Juergen Hoeller 6403479902 TypeDescriptor's nested type traversal leniently returns null in case of unresolvable nested type
Issue: SPR-11898
(cherry picked from commit d663580)
2014-07-01 12:00:20 +02:00
Juergen Hoeller 5af1a691bc DefaultAdvisorChainFactory never passes null into ClassFilter, enabling async advisor to work without target class as well
Issue: SPR-11910
(cherry picked from commit a9b650f)
2014-07-01 11:59:43 +02:00
Juergen Hoeller 9f967b1d81 SharedEntityManagerCreator immediately throws TransactionRequiredException on persist, merge, remove etc (as required by JPA spec)
Issue: SPR-11923
(cherry picked from commit 045d735)
2014-07-01 11:59:11 +02:00
Juergen Hoeller e50507206f DefaultSubscriptionRegistry's removeSubscriptionInternal defensively handles non-existing destinations
Issue: SPR-11832
(cherry picked from commit 5a8e470)
2014-07-01 11:58:08 +02:00
Juergen Hoeller c73ac075c4 UriComponentBuilder allows for multiple independent build() calls on same builder instance
Issue: SPR-11885
(cherry picked from commit d239016)
2014-07-01 11:57:45 +02:00
Juergen Hoeller 0bf0901b8f SelectTag consistently checks specified 'multiple' attribute now, never falling back to forceMultiple in case of user-provided value
Issue: SPR-11903
(cherry picked from commit 779ca99)
2014-07-01 11:57:15 +02:00
Juergen Hoeller 7d94b5e853 FrameworkPortlet properly initializes StandardPortletEnvironment's property sources and exposes local PortletRequestAttributes in case of pre-bound ServletRequestAttributes as well
Issue: SPR-11816
Issue: SPR-11295
2014-07-01 11:55:19 +02:00
Juergen Hoeller 8ddbbc2e67 PathMatchingResourcePatternResolver's findPathMatchingResources needs to check for VFS before checking isJarResource
ResourceUtils isFileURL also detects "vfsfile" as a file system protocol (again).

Issue: SPR-11887
2014-07-01 11:54:16 +02:00
Juergen Hoeller 0a34f86333 MBeanExportConfiguration's SpecificPlatform properly calls afterPropertiesSet
Also makes the nested SpecificPlatform enum public for Spring Boot to reuse it.

Issue: SPR-11877
(cherry picked from commit 6f68b03)
2014-07-01 11:52:53 +02:00
Juergen Hoeller a0c86ae455 WebSphereUowTransactionManager exposes SmartTransactionObject
Issue: SPR-11876
(cherry picked from commit 03f3412)
2014-07-01 11:51:33 +02:00
Juergen Hoeller 0761ee99ae Workaround for WFLY-3474 NullPointerException
Prior to this commit, the ServletResponseHttpHeaders.get method
would throw an NPE when used under Wildfly 8.0.0.Final and 8.1.0.Final.
This can be traced to WFLY-3474, which throws an NPE when calling
HttpServletResponse.getHeaders("foo") and that header has not
been defined prior to that.
This would cause NPE being thrown by AbstractSockJsService when
checking for CORS HTTP headers in the server HTTP response.

This commit surrounds that method call in AbstractSockJsService and
guards against this issue.

Issue: SPR-11919
(cherry picked from commit 24cdefb)
2014-07-01 11:51:01 +02:00
Juergen Hoeller 9054f4fb58 HttpHeaders fails getAllow if set to EmptyCollection
Prior to this commit, calls to getAllow would fail is setAllow was set
to an EmptyCollection right before.

    java.lang.IllegalArgumentException: No enum constant
    org.springframework.http.HttpMethod

This commit fixes this by testing the header value for an empty value
before trying to use it to get a value from the Enum.

Issue: SPR-11917
(cherry picked from commit 9919a98)
2014-07-01 11:46:53 +02:00
Rossen Stoyanchev 41e78d0f50 Fix failing test 2014-06-29 22:08:25 -04:00
Rossen Stoyanchev 526d5ba253 Fix warnings from sniff task on master 2014-06-29 17:44:43 -04:00
Rossen Stoyanchev 40c203ca71 Minor fix in STOMP broker relay
This is a backport for a change made as part of:
https://github.com/spring-projects/spring-framework/commit/113fd1180a14656a89d6d6639d259c577d70fbc5

Issue: SPR-11884
2014-06-29 16:58:47 -04:00
Rossen Stoyanchev d18fc53148 Avoid multiple invocations of afterConnectionClosed
This change ensures the state of a SockJS session is set to CLOSED
immediately after close is invoked. This avoids duplicate invocations
of afterConnectionClosed in WebSocket transport.

This is a backport of:
https://github.com/spring-projects/spring-framework/commit/3af488a701834f61b89cd84040605a6252962e9c

Issue: SPR-11884
2014-06-29 16:58:13 -04:00
Rossen Stoyanchev 618771d59d Add check for unused WebSocket sessions
Sessions connected to a STOMP endpoint are expected to receive some
client messages. Having received none after successfully connecting
could be an indication of proxy or network issue. This change adds
periodic checks to see if we have not received any messages on a
session which is an indication the session isn't going anywhere
most likely due to a proxy issue (or unreliable network) and close
those sessions.

This is a backport for commit:
https://github.com/spring-projects/spring-framework/commit/a3fa9c979777e554efad0df429041767f05dfdb8

Issue: SPR-11884
2014-06-29 16:58:13 -04:00
Rossen Stoyanchev 87077d3fad Add support for setting removeOnCancelPolicy
This change introduces removeOnCancelPolicy on ThreadPoolTaskScheduler
and ScheduledExecutorFactoryBean and sets it to true for SockJS.
This ensures that cancelled tasks are removed immediately to avoid
the "unbounded retention of cancelled tasks" that is mentioned in
the Javadoc ScheduledThreadPoolExecutor:

"By default, such a cancelled task is not automatically removed from
the work queue until its delay elapses. While this enables further
inspection and monitoring, it may also cause unbounded retention of
cancelled tasks. To avoid this, set setRemoveOnCancelPolicy to true,
which causes tasks to be immediately removed from the work queue at
time of cancellation."

This is a backport for:
https://github.com/spring-projects/spring-framework/commit/7441f2301281049cff7224bf650646490388080e

Issue: SPR-11918
2014-06-29 16:57:58 -04:00
Rossen Stoyanchev c0c3618906 Fix concurrency issues in SockJS session impls
Cherry-picked from:
https://github.com/spring-projects/spring-framework/commit/fcf6ae83285890f2e8e7de77dcc6e633129978e8

Issue: SPR-11916
2014-06-29 15:50:55 -04:00
Spring Buildmaster 0405bb401a Next development version 2014-05-20 06:41:20 -07:00
Juergen Hoeller e3e71ba92a Servlet 3 multipart request implements getParameterMap defensively as well
Issue: SPR-11074
(cherry picked from commit c7d1c49)
2014-05-20 11:11:56 +02:00
Juergen Hoeller d4e1b9eb4c Polishing
(cherry picked from commit 6fef8b9)
2014-05-20 11:11:33 +02:00
Rossen Stoyanchev 44ee51a6c9 Disable URL resolution in DTD declarations
Issue: SPR-11768
2014-05-19 22:23:51 -04:00
Juergen Hoeller ba6d187b5c Consistent MvcUriComponentsBuilder assertion handling
(cherry picked from commit 61b47ba)
2014-05-20 01:51:33 +02:00
Juergen Hoeller 54636b3f7c Further UriComponentsBuilder javadoc revision 2014-05-20 01:13:18 +02:00
Juergen Hoeller 545c28fd4e Minor UriComponentsBuilder javadoc revision 2014-05-20 00:47:03 +02:00
Juergen Hoeller 95a7bfd327 Consistent use of IllegalStateException instead of InternalError for UnsupportedEncodingException cause
(cherry picked from commit d9b39ad)
2014-05-20 00:42:48 +02:00
Juergen Hoeller ccebbf74ec Latest patches from ASM trunk
(cherry picked from commit cfc720d)
2014-05-19 22:59:39 +02:00
Juergen Hoeller c350080f99 StringUtils.parseLocaleString parses variant correctly when variant contains country code
This commit also includes a JUnit 4 style revision of StringUtilsTests and ObjectUtilsTests.

Issue: SPR-11806
(cherry picked from commit 295a6ae)
2014-05-19 22:46:47 +02:00
Juergen Hoeller 6b9738fd68 Building against latest javax.el 2.2.x version
(cherry picked from commit f73a8ba)
2014-05-19 20:46:42 +02:00
Juergen Hoeller 1120680c65 Consistently log Class.getName() instead of Class.toString(), avoiding double class term in log message
Issue: SPR-11804
(cherry picked from commit 2619955)
2014-05-19 20:46:14 +02:00
Juergen Hoeller a2ef2c9d3e Refined check for NoClassDefFoundError in getTestExecutionListeners()
Issue: SPR-11804
(cherry picked from commit 41ed228)
2014-05-19 17:28:37 +02:00
Juergen Hoeller 1bbc032071 Backported proper updateAccessedAttributes test
Issue: SPR-11738
(cherry picked from commit 6188550)
2014-05-19 16:42:42 +02:00
Juergen Hoeller c70a81a805 Javadoc fixes 2014-05-19 00:08:46 +02:00
Juergen Hoeller 3c709a763d Servlet 3 multipart request implements getParameterNames defensively (for WebLogic 12 compatibility)
This commit also includes lazy resolution support for StandardServletMultipartResolver, along the lines of existing lazy mode in CommonsMultipartResolver.

Issue: SPR-11074
Issue: SPR-11730
(cherry picked from commit 82336c3)
2014-05-18 20:27:44 +02:00
Juergen Hoeller 7d78c65187 Properly evaluate @Conditional in case of multiple imports for same config class (fixing regression in Spring Boot)
Issue: SPR-11788
2014-05-18 02:00:11 +02:00
Rossen Stoyanchev 748167bfa3 Improve StringUtils.cleanPath
Issue: SPR-11793
2014-05-16 11:27:55 -04:00
Juergen Hoeller 3e70013b55 JmsResourceHolder checks for nested DataSource transactions as well (for Oracle AQ compatibility)
Issue: SPR-11791
(cherry picked from commit 5faacd5)
2014-05-16 15:36:16 +02:00
Juergen Hoeller ea9ad4ee9b Properly evaluate @Conditional in case of multiple imports for same config class
Issue: SPR-11788
(cherry picked from commit 52f44b3)
2014-05-16 15:35:56 +02:00
Rossen Stoyanchev 482eff81e1 Await TcpClient shutdown in STOMP relay 2014-05-15 21:46:44 -04:00
Juergen Hoeller c706cbbed4 Latest possible dependency updates for spring-orm
(cherry picked from commit 0d22719)
2014-05-15 17:35:32 +02:00
Juergen Hoeller 7bc38acbf6 Polishing 2014-05-15 15:23:11 +02:00
Juergen Hoeller 297e4eec36 Keep unused MemorySafeUndeclaredThrowableStrategy around in deprecated form for the 4.0.x line
Issue: SPR-11782
2014-05-15 15:05:00 +02:00
Juergen Hoeller 235b65d103 Polishing
(cherry picked from commit b0f0d2f)
2014-05-15 14:43:02 +02:00
Juergen Hoeller 8a28645dd6 ResultSetWrappingSqlRowSet preserves first matching column per name (as defined in ResultSet's javadoc)
Issue: SPR-11786
(cherry picked from commit 0728e32)
2014-05-15 14:40:43 +02:00
Juergen Hoeller f94ded830d Consistent use of ClassUtils.forName instead of class.getClassLoader().loadClass
Issue: SPR-11780
(cherry picked from commit 551950c)
2014-05-15 14:40:15 +02:00
Juergen Hoeller ad8f17b6af Test compatibility with JasperReports 5.5.2 2014-05-12 23:35:17 +02:00
Juergen Hoeller 261520cea0 Undertow-related polishing
(cherry picked from commit 2750ab6)
2014-05-12 23:32:12 +02:00
Juergen Hoeller 00aa40b8da Consistent EhCache version between 4.1 and 4.0.5 2014-05-12 23:27:16 +02:00
Juergen Hoeller ac9b64e528 Consistent declaration of JSP, JSTL and JavaMail API dependencies; updated several dependencies to latest maintenance releases (Tiles 3.0.4, Jetty 9.1.5) 2014-05-12 21:50:13 +02:00
Juergen Hoeller 1e7fade89e JasperReports-related polishing
(cherry picked from commit 782d10c)
2014-05-12 20:50:24 +02:00
Stephane Nicoll 3c58be05a5 Fix typo
Issue: SPR-11571
(cherry picked from commit 6551aa6)
2014-05-08 16:38:08 +02:00
Juergen Hoeller ef290ff95c Additional tests for configuration class importing via ASM
Issue: SPR-11647
(cherry picked from commit 8c9116f)
2014-05-08 16:31:07 +02:00
Juergen Hoeller ae45794451 IdToEntityConverter defensively handles access to getDeclaredMethods
Issue: SPR-11758
(cherry picked from commit 381ccde)
2014-05-08 16:30:45 +02:00
Juergen Hoeller fccec210b4 GenericTypeResolver returns null for entirely unresolvable type arguments only
Issue: SPR-11763
(cherry picked from commit bea34ea)
2014-05-08 16:28:53 +02:00
Sebastien Deleuze 96da77ef75 Avoid ConcurrentModificationException
Removal of cached destination is now moved outside the for loop
that removes subscriptions to avoid ConcurrentModificationException.

Also since updateCache is a LinkedHashMap with accessOrder=true,
a simple access with updateCache.get() modify the map.
By iterating over updateCache.entrySet(), we avoid this update.

Issue: SPR-11755
2014-05-06 20:22:05 -04:00
Juergen Hoeller c9417d0610 Fixed invalid code tag in javadoc
(cherry picked from commit a139670)
2014-05-01 10:55:55 +02:00
Spring Buildmaster 085e52fc31 Next development version 2014-04-30 15:41:11 -07:00
Juergen Hoeller 8f175046c8 spring-orm-hibernate4 requires aopalliance dependency now (after propdeps upgrade) 2014-04-30 23:19:07 +02:00
Juergen Hoeller c1dbd9f150 Upgraded to propdeps plugin 0.0.6
(cherry picked from commit a842b93)
2014-04-30 22:58:56 +02:00
Juergen Hoeller 42a35ef3be AnnotationMetadataReadingVisitor passes metaAnnotationMap into getMergedAnnotationAttributes algorithm, for finding out about applicable overrides
Issue: SPR-11649
(cherry picked from commit 842a8a8)
2014-04-30 22:57:09 +02:00
Rossen Stoyanchev 21fd68150a Log ignored CONNECT messages at error level
Issue: SPR-11673
2014-04-30 11:12:32 -04:00
Rossen Stoyanchev d20259be1d Log STOMP ERROR frames at error level
Issue: SPR-11673
2014-04-30 11:01:18 -04:00
Rossen Stoyanchev 6ca921021c Update log level
Issue: SPR-11673
2014-04-30 10:28:27 -04:00
Rossen Stoyanchev eab9d24c31 Fix Javadoc typo 2014-04-30 10:07:51 -04:00
Juergen Hoeller 15749c2a9d Upgraded to Gradle 1.12 and updated several dependencies to latest maintenance releases
(cherry picked from commit e84f61b)
2014-04-30 14:32:12 +02:00
Juergen Hoeller 93b0f0b126 JRubyScriptUtils defensively handles null Nodes in findClassNode (fails against JRuby 1.7.12 otherwise)
Issue: SPR-11747
(cherry picked from commit adb616b)
2014-04-30 14:32:07 +02:00
Juergen Hoeller 27b2ed1614 Spring Framework build uses Reactor 1.1 GA now, getting rid of last remaining pre-GA dependency 2014-04-30 11:41:57 +02:00
Rossen Stoyanchev 790d62bcb1 Simplify and improve STOMP broker relay int tests 2014-04-29 23:01:40 -04:00
Rossen Stoyanchev 563476f57c Split destination cache into access vs update
Issue: SPR-11657
2014-04-29 22:16:49 -04:00
Rossen Stoyanchev 79de45b805 Add cache limit to DefaultSessionRegistry and polish
Issue: SPR-11657
2014-04-29 18:17:40 -04:00
Sebastien Deleuze 63a868dafb Fix DefaultSubscriptionRegistry when using pattern destinations
DestinationCache is now used for both plain and pattern
destinations. It stores internally the subscriptions map for each
cached destination. Subscriptions are initially created when there
is no cache for the requested destination, and are updated when
subscriptions change.

Issue: SPR-11657
2014-04-29 18:17:30 -04:00
Juergen Hoeller 1afdd9bd75 Polishing
(cherry picked from commit 02aca9c)
2014-04-30 00:10:58 +02:00
Juergen Hoeller d0c839f0eb Polishing 2014-04-29 16:21:06 +02:00
Juergen Hoeller 744727b8aa AbstractAdvisingBeanPostProcessor uses target class check for existing proxy but checks against actual exposed object otherwise (catching introductions)
Issue: SPR-11725
(cherry picked from commit a0658c5)
2014-04-29 16:01:44 +02:00
Rossen Stoyanchev 9fbb7394e2 Polish STOMP documentation 2014-04-28 22:35:51 -04:00
Sebastien Deleuze 80cb0c4e5b Include more guidance about DispatcherServlet context
Also update <mvc:annotation-driven /> comment in XSD.

Issue: SPR-11703
2014-04-28 22:10:52 -04:00
Rossen Stoyanchev 5c4804f4a4 Document STOMP-related ApplicationContext events
Issue: SPR-11672
2014-04-28 21:59:09 -04:00
Juergen Hoeller a679f3e7a3 Polishing
(cherry picked from commit be5f2a8)
2014-04-28 23:52:23 +02:00
Juergen Hoeller bd5b3749c5 Revised @PropertySource parsing for consistent PropertySource naming, avoiding accidental overriding by name
Issue: SPR-11637
(cherry picked from commit ab24dda)
2014-04-28 23:47:33 +02:00
Juergen Hoeller 89398b0811 AspectJExpressionPointcut defensively handles fallback expression parsing
Issue: SPR-9335
(cherry picked from commit ce4912b)
2014-04-28 23:47:25 +02:00
Juergen Hoeller a87c9b8c5c Test for base package specified as config location
Issue: SPR-11647
(cherry picked from commit 8e6e6c2)
2014-04-28 23:47:14 +02:00
Juergen Hoeller d0f9853769 Test for overriding singleton @Bean method with scoped proxy in configuration subclass
Issue: SPR-10744
(cherry picked from commit 299776f)
2014-04-28 23:46:51 +02:00
Juergen Hoeller bed739ce92 GenericBeanDefinition's toString() takes parent definition into account
Issue: SPR-9671
(cherry picked from commit 0ef29b2)
2014-04-28 23:46:40 +02:00
Rossen Stoyanchev cb712afa97 Improve handling of disconnects in STOMP broker relay
This is a backport of:
https://github.com/spring-projects/spring-framework/commit/990f5bb720ac172fa659a59339df06065d31c0bf

Issue: SPR-11655
2014-04-28 10:08:00 -04:00
Juergen Hoeller c97c246940 Polishing 2014-04-28 00:29:04 +02:00
Juergen Hoeller 4196e6c96f AbstractMarshaller avoids SAXSource workaround when processExternalEntities=true
Issue: SPR-11737
(cherry picked from commit 93d13cf)
2014-04-28 00:27:04 +02:00
Juergen Hoeller 59cef3ce81 General defensiveness about the bootstrap ClassLoader (i.e. null ClassLoader)
Issue: SPR-11721
2014-04-28 00:26:18 +02:00
Juergen Hoeller c8ea80d7ed Configuration class processing explicitly skips java.* classes since we'll never find @Bean annotations there anyway
Issue: SPR-11718
(cherry picked from commit 470e9c8)
2014-04-28 00:17:19 +02:00
Juergen Hoeller 656fc52ff9 @Bean processing explicitly ignores bridge methods (for method overrides with return type narrowing on JDK 8)
Issue: SPR-11718
(cherry picked from commit dc93406)
2014-04-28 00:16:38 +02:00
Rossen Stoyanchev a4d6f8473e Upgrade to reactor 1.1 RC1 2014-04-25 12:32:36 -04:00
Rossen Stoyanchev 443fb8e4ee Fix issue with subscribe destination
The original fix for SPR-11423:
https://github.com/spring-projects/spring-framework/commit/32e5f57e647022d9ea82c03670936bf31f8467de

was insufficient when using an external broker since the original
destination header has to be in the "native headers" map (i.e. with
STOMP headers) in order to be included in messages broadcast by
the broker.
2014-04-25 12:17:08 -04:00
Juergen Hoeller 95b1cb7173 AspectJ 1.8 final used in build, plus TestNG preparations for optional -target 1.8 usage
Issue: SPR-11212
Issue: SPR-11699
2014-04-24 11:09:39 +02:00
Juergen Hoeller 51fb485181 Polishing
(cherry picked from commit 9353332)
2014-04-24 10:32:38 +02:00
Juergen Hoeller f16e6c4105 General defensiveness about the bootstrap ClassLoader (i.e. null ClassLoader)
Issue: SPR-11721
(cherry picked from commit c05ab3e)
2014-04-24 10:31:48 +02:00
Juergen Hoeller 4dbc0c296c Polishing
(cherry picked from commit ec7d80b)
2014-04-24 10:31:39 +02:00
Juergen Hoeller d71d38bfaf ServletServerHttpResponse specifically checks for Servlet 3.0's HttpServletResponse.getHeader(String) method
Issue: SPR-11712
(cherry picked from commit 21f9ca0)
2014-04-24 10:31:29 +02:00
Juergen Hoeller eb28259371 SpringProperties falls back to ClassLoader.getSystemResource when loaded in bootstrap ClassLoader
Issue: SPR-11721
(cherry picked from commit 9cb5f48)
2014-04-24 10:31:20 +02:00
Juergen Hoeller 7ae6a60f43 checkNotModified leniently handles IE-10-style If-Modified-Since values and silently proceeds if header value cannot be parsed at all
Issue: SPR-11727
(cherry picked from commit 794e859)
2014-04-24 10:30:49 +02:00
Juergen Hoeller d3c9a31e9a DispatcherServlet skips multipart resolution if error page exception attribute indicates MultipartException as root cause
Issue: SPR-11716
(cherry picked from commit 5b47816)
2014-04-24 10:30:12 +02:00
Juergen Hoeller 5aa126600f Final patches from ASM 5.0.2 release
Issue: SPR-11212
(cherry picked from commit fb66567)
2014-04-24 10:29:50 +02:00
Juergen Hoeller 2f15f72fcc ShallowEtagHeaderFilter writes body early on sendError/sendRedirect and interprets setContentLength/setBufferSize as a hint for capacity increase
Issue: SPR-11705
Issue: SPR-11717
(cherry picked from commit 3f392e3)
2014-04-24 10:28:42 +02:00
Juergen Hoeller d5aacdefd9 Polishing
(cherry picked from commit 700c3b2)
2014-04-24 10:27:43 +02:00
Juergen Hoeller e379e77b96 considerInterfaces should work without considerInherited as well
Issue: SPR-11719
(cherry picked from commit 5ab7076)
2014-04-24 10:27:15 +02:00
Juergen Hoeller 9c45755890 AnnotationTypeFilter prevents ASM-based loading of java.* interfaces as well
Issue: SPR-11719
(cherry picked from commit 945335d)
2014-04-24 10:26:42 +02:00
Juergen Hoeller 5962fc2590 EQ/NE do not fail in case of a Comparable mismatch and apply a specific CharSequence equality check
Issue: SPR-11708
(cherry picked from commit 66bae99)
2014-04-24 10:26:08 +02:00
Rossen Stoyanchev 1b59b4eb26 Add Reactor 11 support
This change adds support for Reactor 1.1 in spring-messaging in
addition to Reactor 1.0.1 -- whichever is present on the classpath is
used.

Note also the module name change:
reactor-tcp:1.0.1 -> reactor-net:1.1.0

Issue: SPR-11636
2014-04-23 23:35:49 -04:00
HejiaHo f6b89c2ca9 Fix ConcurrentReferenceHashMap max constraints
Update calculateShift to respect the maximum upper bound as well as the
minimum value.

Issue: SPR-11720

(cherry picked from commit 16410cad)
2014-04-22 15:03:23 +01:00
Sam Brannen 82c32db5a1 Don't mutate annotation metadata when merging attrs
Prior to this commit, invoking the getMergedAnnotationAttributes()
method in AnnotationReadingVisitorUtils resulted in mutation of the
internal state of the ASM-based annotation metadata supplied to the
method.

This commit fixes this issue by making a copy of the original
AnnotationAttributes for the target annotation before merging attribute
values from the meta-annotation hierarchy.

This commit also introduces a slight performance improvement by
avoiding duplicate processing of the attributes of the target
annotation.

Issue: SPR-11710
(cherry picked from commit e1720d89fc)
2014-04-21 12:50:27 -04:00
Juergen Hoeller 52f580149f Polishing 2014-04-17 22:42:33 +02:00
Juergen Hoeller 271fe4f554 Polishing
(cherry picked from commit 48c977a)
2014-04-17 22:14:31 +02:00
Juergen Hoeller 02e8198283 MessageConversionException offers constructor without cause argument now, plus related polishing
Issue: SPR-11653
(cherry picked from commit 2888775)
2014-04-17 22:14:01 +02:00
Juergen Hoeller 090ab4bb6d XStreamMarshaller supports custom NameCoder strategy
Issue: SPR-11702
(cherry picked from commit f5cce14)
2014-04-17 21:39:34 +02:00
Juergen Hoeller 18ef1d4f76 WebSocket intro correctly points to annotations section
Issue: SPR-11667
(cherry picked from commit 53162e7)
2014-04-17 21:39:02 +02:00
Juergen Hoeller d9cb44527c Backported tests for package-visible methods with CGLIB proxies
Issue: SPR-11618
(cherry picked from commit 90309ab)
2014-04-17 21:38:01 +02:00
Juergen Hoeller 8e44521ec4 Latest ASM patches (fix for bug 317151 from ASM HEAD; ASM's 1.8 bytecode processing needs to be lenient with CGLIB 3.1)
Issue: SPR-11212
(cherry picked from commit 637ad20)
2014-04-17 21:34:57 +02:00
Juergen Hoeller d28c6d8bdb Consistent documentation for both 'close' and 'shutdown' as inferred destroy methods
Issue: SPR-11680
(cherry picked from commit 14f9dbf)
2014-04-17 21:32:09 +02:00
Juergen Hoeller c9432ce499 JDBC 3.0 related javadoc overhaul
Issue: SPR-11600
(cherry picked from commit 3fef358)
2014-04-17 21:31:45 +02:00
Stephane Nicoll 2d8e0c8f87 Fix expression cache
Prior to this commit, only the java.lang.reflect.Method was used to
identify an annotated method. As a result, if different annotations
were placed on different methods (method overriding, interface
implementation) only the first one (cached) was used.

LazyParamAwareEvaluationContext was affected by the exact
same problem and has been also fixed.

Issue: SPR-11692
(cherry picked from commit df34bab)
2014-04-15 09:29:56 +02:00
Sam Brannen 03ae8eeb95 Make EOF_STATEMENT_SEPARATOR XML friendly
Changed the value of ScriptUtils.EOF_STATEMENT_SEPARATOR from
"<<< END OF SCRIPT >>>" to "^^^ END OF SCRIPT ^^^" so that the angle
brackets do not have to be escaped in XML configuration files.

Issue: SPR-11687
(cherry picked from commit 1753f5d1ca)
2014-04-11 18:27:59 +02:00
Sam Brannen 9230b38aea Support EOF as statement separator in SQL scripts
Prior to Spring Framework 4.0.3, it was possible to supply a bogus
statement separator (i.e., a separator string that does not exist in
the configured SQL scripts) to ResourceDatabasePopulator with the side
effect that the entire contents of a script file would be interpreted
as a single SQL statement.

This undocumented feature was never intentional; however, some
developers came to rely on it. Unfortunately, changes made in
conjunction with SPR-9531 and SPR-11560 caused such scenarios to no
longer work.

This commit introduces first-class support for executing scripts which
contain a single statement that spans multiple lines but is not
followed by an explicit statement separator.

Specifically, ScriptUtils.EOF_STATEMENT_SEPARATOR may now be specified
as a 'virtual' statement separator to denote that a script contains a
single statement and no actual separator.

Issue: SPR-11687
(cherry picked from commit cc0ae3a881)
2014-04-11 18:25:06 +02:00
Sam Brannen d5ce30f360 Deprecate custom/default CtxLdr class name in TCF
Once the new bootstrap strategy for the TestContext framework (TCF) is
introduced in Spring Framework 4.1, a TestContextBootstrapper will
assume full responsibility for determining what ContextLoader to use as
the default. Consequently, the previous support for supplying the class
name for a custom, default ContextLoader will no longer be applicable.

This commit therefore officially deprecates support for custom, default
ContextLoader class names via the following mechanisms:

 - The TestContextManager(Class, String) constructor

 - The getDefaultContextLoaderClassName(Class) method in
   SpringJUnit4ClassRunner

Issue: SPR-11682
2014-04-10 17:54:14 +02:00
Sam Brannen 428aee5b72 Deprecate getDefTELClasses in TestContextMgr
Since a dedicated bootstrap strategy will be introduced for the
TestContext framework in Spring Framework 4.1, this commit officially
deprecates TestContextManager.getDefaultTestExecutionListenerClasses()
as a forewarning to developers or frameworks that may be using this
obscure feature.

Issue: SPR-11679
2014-04-09 22:20:43 +02:00
Juergen Hoeller f7a17added AbstractMarshaller uses general exception message in extracted buildDocument() method
Issue: SPR-11635
2014-04-09 20:54:41 +02:00
Juergen Hoeller 196f629a20 JBoss "vfszip" resources need to be treated as jar URLs
Issue: SPR-11676
(cherry picked from commit be6b54f)
2014-04-09 20:51:23 +02:00
Juergen Hoeller 7135e729e2 Dropped JCache RC repo (now unused); minor dependency upgrades
Issue: SPR-11640
(cherry picked from commit 9e1631d)
2014-04-09 19:00:44 +02:00
Juergen Hoeller 21874627d2 Polishing
Issue: SPR-11637
(cherry picked from commit 0041e24)
2014-04-09 19:00:23 +02:00
Juergen Hoeller 3ab88b857b AbstractMarshaller pre-implements getDefaultEncoding() method
Issue: SPR-11635
(cherry picked from commit d4b0ae9)
2014-04-09 19:00:08 +02:00
Juergen Hoeller 294545d07a XStreamMarshaller lazily creates fallback XppDriver
Issue: SPR-11635
(cherry picked from commit 8f28a93)
2014-04-09 18:59:47 +02:00
Juergen Hoeller 38cd79047a SelectTag correctly detects multiple="true" again
Issue: SPR-11678
(cherry picked from commit 8d8766d)
2014-04-09 18:59:37 +02:00
Stephane Nicoll 8a779c32d5 Update to JCache 1.0.0 final
Issue: SPR-11640
(cherry picked from commit 0bdece7)
2014-04-08 15:20:57 +02:00
Sam Brannen 7ba31dee45 Use unconstrained quotes in reference manual
Prior to this commit, there were numerous places in the reference
manual, where we see output similar to the following:

    BeanDefinition`s with the `ApplicationContext

This commit addresses this issue by using unconstrained quotes
(e.g., ++XYZ++s) instead of backticks (e.g., `XYZ`s) when the formatted
text is immediately followed by an "s".

This commit also corrects a few typos and corrects natural English
pluralization of Java code elements in the reference manual where
appropriate -- for example, "@Controllers" becomes "@Controller classes,
etc.

Issue: SPR-11650
(cherry picked from commit 0eba1f818f)
2014-04-04 22:05:43 +02:00
Brian Clozel 1c45d7573c Fix @SubscribeMapping MESSAGE response destination
Prior to this commit, @SubscribeMapping mapped methods (backed with
@SendTo* annotations, or not) would send MESSAGEs with the wrong
destination. Instead of using the original SUBSCRIBE destination, it
would use the lookup path computed from the configured prefixes in the
application.

This commit fixes this issue - now @SubscribeMapping MESSAGEs use the
original SUBSCRIBE destination.

Issue: SPR-11648
2014-04-04 12:45:19 +02:00
Juergen Hoeller f014bbb5cf Revised ByteArrayOutputStream handling in MarshallingView and co
Issue: SPR-11646
(cherry picked from commit 8006696)
2014-04-02 21:29:37 +02:00
Juergen Hoeller d1030b798d ResourceHttpRequestHandler explicitly closes a Resource's InputStream
Issue: SPR-11644
(cherry picked from commit 3a96f16)
2014-04-02 21:29:05 +02:00
Juergen Hoeller d628025f13 Polishing
Issue: SPR-11262
2014-04-02 21:28:42 +02:00
Rossen Stoyanchev 30ea1a3475 Fix issue with default executor for message channels
This change ensures correct default settings for message channel's
created through the websocket message-broker XML namespace even
when the channels are customized for other reasons -- e.g. to add
a channel interceptor.

Issue: SPR-11623
2014-04-01 14:16:10 -04:00
Rossen Stoyanchev 7b014eaa55 Improve access to WebSocketSession fields
Ensure the Standard- and the JettyWebSocketSession can return the
Principal and accepted WebSocket sub-protocol even after the
session is closed.

Issue: SPR-11621
2014-04-01 14:16:10 -04:00
Rossen Stoyanchev e21c47d4ce Optimize performance in StompEncoder/Decoder escaping
Issue: SPR-11643
2014-04-01 14:16:10 -04:00
Rossen Stoyanchev 632ae6a4df Improve shutdown responsiveness of SubProtocolWSH
Proactively notify all active WebSocket sessions when a shutdown is
progress. Sessions then can ignore further attempts to send messages
and also stop stop trying to flush messages right away.
2014-04-01 14:16:10 -04:00
Sam Brannen 989f6194b6 Support classes AND locations in @ContextConfiguration
Prior to this commit, the Spring TestContext Framework did not support
the declaration of both 'locations' and 'classes' within
@ContextConfiguration at the same time.

This commit addresses this in the following manner:

 - ContextConfigurationAttributes no longer throws an
   IllegalArgumentException if both 'locations' and 'classes' are
   supplied to its constructor.

 - Concrete SmartContextLoader implementations now validate the
   supplied MergedContextConfiguration before attempting to load the
   ApplicationContext. See validateMergedContextConfiguration().

 - Introduced tests for hybrid context loaders like the one used in
   Spring Boot. See HybridContextLoaderTests.

 - Updated the Testing chapter of the reference manual so that it no
   longer states that locations and classes cannot be used
   simultaneously, mentioning Spring Boot as well.

 - The Javadoc for @ContextConfiguration has been updated accordingly.

 - Added hasLocations(), hasClasses(), and hasResources() convenience
   methods to MergedContextConfiguration.

Issue: SPR-11634
(cherry picked from commit 1f017c4acb)
2014-04-01 19:54:04 +02:00
Sam Brannen 17bf5b991f Update Javadoc for supported JBoss VFS version
(cherry picked from commit 34eb4dba3a)
2014-03-30 16:02:27 +02:00
Sam Brannen cd9d7cfe4f Reinject Servlet mocks between TestNG test methods
Prior to this commit, if multiple test methods were executed in a
subclass of AbstractTestNGSpringContextTests annotated with
@WebAppConfiguration, then injected Servlet API mocks would only
reference the mocks created for the first test method. Subsequent test
methods could therefore never reference the current mocks, and there
was a discrepancy between the state of the injected mocks and the mock
set in the RequestContextHolder.

This commit addresses this issue by ensuring that dependencies
(including updated mocks) are injected into the test instance before
the next test method if the ServletTestExecutionListener resets the
request attributes in RequestContextHolder.

Issue: SPR-11626
(cherry picked from commit c38600762d)
2014-03-29 21:46:58 +01:00
Spring Buildmaster fb7e1970a9 Next development version 2014-03-26 21:25:05 -07:00
Juergen Hoeller 9859b97037 Consider a null ClassLoader (typically the bootstrap CL) as cache-safe
Issue: SPR-11606
(cherry picked from commit a4a2e80)
2014-03-26 23:51:53 +01:00
Rossen Stoyanchev 32852e0843 Improve doc on authentication for stomp/websocket 2014-03-26 17:12:30 -04:00
Rossen Stoyanchev b02bda95b2 Document better ASYNC dispatch type config for Filters
Although the need to map the ASYNC dispatcher type to a Filter was
already mentioned, it wasn't very prominent and can be quite critical
in some cases. This change addresses that.

Issue: SPR-10440
2014-03-26 17:12:10 -04:00
Juergen Hoeller b70148c12d Consistent PropertyAccessor method order as declared in the interface
Issue: SPR-11609
2014-03-26 21:47:56 +01:00
Juergen Hoeller 3af8a3260a Correctly resolve accessors for static properties on Class
Issue: SPR-11609
2014-03-26 21:46:38 +01:00
Juergen Hoeller e3035363a6 Maintenance version updates, excludes for overlapping dependencies (PR #499) 2014-03-26 18:15:23 +01:00
Rossen Stoyanchev e92bbc8014 Revert "Improve suffix pattern check"
This reverts commit 3474afb165.

Unfortunately this change is likely to cause issues for applications
that use regular expressions in a URI variable. I think we will have
to leave at: if there are any dots in the last segment of the
request path, regardless of whether they're in a URI var or not,
the suffix pattern match is off.

Issue: SPR-11532
2014-03-26 11:37:11 -04:00
Rossen Stoyanchev 3347b45292 Provide more accurate error message 2014-03-26 11:32:34 -04:00
Rossen Stoyanchev e6e12be5ef Fix typo in documentation 2014-03-26 11:32:34 -04:00
Juergen Hoeller b9bac1d3b6 Relaxed getElementTypeDescriptor assertion to not insist on a ResolvableType-known array
Issue: SPR-11608
2014-03-26 16:09:15 +01:00
Juergen Hoeller 3388573646 AbstractApplicationEventMulticaster only caches if event type and source type are cache-safe
Issue: SPR-11606
2014-03-26 15:29:50 +01:00
Phillip Webb 2b5239543d Revert "Next development version"
This reverts commit 4788875a4b.
2014-03-26 01:22:53 -07:00
Spring Buildmaster 4788875a4b Next development version 2014-03-25 22:44:27 -07:00
Rossen Stoyanchev 5dbcd76a71 Add doc section on configuration and performance
Issue: SPR-11450
2014-03-26 00:20:35 -04:00
Rossen Stoyanchev fd175180b9 Revise section explaining the flow of STOMP messages 2014-03-25 22:15:12 -04:00
Rossen Stoyanchev 84133c86fe Update SockJS overview section and polish 2014-03-25 22:15:12 -04:00
Juergen Hoeller 90512f036b Fixed SPR issue reference and aligned exception messages
Issue: SPR-11592
2014-03-26 00:31:38 +01:00
Juergen Hoeller 9fc13e1d23 CacheAspectSupport checks Cache.get(key) once per invocation only
Issue: SPR-11592
2014-03-25 23:56:16 +01:00
Arjen Poutsma f2f355e76c Improved StAX<->SAX bridge
Improved the SAX to StAX (and vice-versa) bridge exposed via StaxUtils.
The old integration had some issues with namespace declaration
attributes, brought to light in a XMLUnit upgrade.

Issue: SPR-11549
2014-03-25 20:58:58 +01:00
Sam Brannen a2f1169e82 Don't detect annotations on superclass in StAnMeta
Changes introduced in conjunction with issue SPR-11475 altered the
behavior of StandardAnnotationMetadata such that annotations could be
detected on superclasses, specifically in the case where the
AnnotatedElementUtils.getAllAnnotationAttributes() method is invoked to
obtain multiple annotations of the same type (on the lowest level in the
class hierarchy), as is the case for @Profile and @Conditional.

This commit partially reverts these changes as follows:

 - All methods in AnnotatedElementUtils now set the
   traverseClassHierarchy to false, thereby effectively reverting the
   changes made in commit 1d30bf83a0.
   Note, however, that the changes made to AnnotationUtils remain in
   place.

 - Introduced tests in AnnotationMetadataTests that verify behavior
   present in Spring Framework 4.0.2 and earlier.

 - Updated tests in AnnotatedElementUtilsTests so that they pass against
   the reverted changes (i.e., align with the behavior present in Spring
   Framework 4.0.2 and earlier).

 - Refined Javadoc in AnnotationMetadata with regard to annotations
   being "present" vs. "defined".

 - Refined Javadoc in AnnotatedTypeMetadata.

Issue: SPR-11475, SPR-11595
2014-03-25 17:48:06 +01:00
Stephane Nicoll d970015d4d Merge pull request #424 from md42/master
* pull424:
  typo in pointcut expression
2014-03-25 17:15:53 +01:00
md42 b0e7f72a27 typo in pointcut expression 2014-03-25 17:15:07 +01:00
Stephane Nicoll c1eb50ef48 polishing 2014-03-25 16:49:54 +01:00
Sebastien Deleuze d67f0803c4 Update WebSocket engines support documentation 2014-03-25 11:05:47 -04:00
Rossen Stoyanchev 2c1d5efbb0 Introduce base exception class for arg resolution
Issue: SPR-11584
2014-03-25 11:02:24 -04:00
Stephane Nicoll 2aee0d8250 Improve MessageMethodArgumentResolver
This commit validates that the payload type of the message is
assignable to the one declared in the method signature. If that
is not the case, a meaningful exception message is thrown with
the types mismatch.

Prior to this commit, only the Message interface could be defined
in the method signature: it is now possible to define a sub-class
of Message if necessary which will match as long as the Message
parameter is assignable to that type.

Issue: SPR-11584
2014-03-25 10:12:29 -04:00
Rossen Stoyanchev bbf101eef6 Fix issue in last commit 2014-03-25 09:59:09 -04:00
Rossen Stoyanchev a247d5f2e8 Guard against exceptions from ApplicationListener
Issue: SPR-11578
2014-03-25 09:05:42 -04:00
Rossen Stoyanchev 8780464c64 Update test to catch CI server issue 2014-03-25 08:24:53 -04:00
Juergen Hoeller 9280ca7749 Upgraded to ASM 5.0.1
Issue: SPR-11239
2014-03-25 11:51:31 +01:00
Rossen Stoyanchev 1c1e1145a2 Allow configuring WebSocket message size in a session
Issue: SPR-11575
2014-03-25 00:27:05 -04:00
Rossen Stoyanchev 5caf36ae91 Update default pools size for SockJS scheduler
This change updates the XML namespace to match a change already made
to the Java config.
2014-03-24 21:44:03 -04:00
Rossen Stoyanchev 13da7057e6 Add session lifecycle ApplicationEvent's
Issue: SPR-11578
2014-03-24 20:30:41 -04:00
Juergen Hoeller 074590730b Polishing 2014-03-25 00:54:02 +01:00
Rossen Stoyanchev c11484b2e7 Add WebSocket transport configuration support
Issue: SPR-11527
2014-03-24 19:20:38 -04:00
Rossen Stoyanchev 1e9960e1ce Add WebSocketTransportRegistration
Issue: SPR-11527
2014-03-24 19:20:38 -04:00
Rossen Stoyanchev 545c4effb1 Polish StompDecoder and the new Buffering sub-class
Issue: SPR-11527
2014-03-24 19:20:37 -04:00
Sebastien Deleuze bbdb72d808 Add configuration for message buffer size limit
BufferingStompDecoder message buffer size limit can now be configured
with JavaConfig MessageBrokerRegistry.setMessageBufferSizeLimit() or
with XML <websocket:message-brocker message-buffer-size="">.

Issue: SPR-11527
2014-03-24 19:20:37 -04:00
Rossen Stoyanchev ebffd67b5e Add BufferingStompDecoder
Before this change the StompDecoder decoded and returned only the first
Message in the ByteBuffer passed to it. So to obtain all messages from
the buffer, one had to loop passing the same buffer in until no more
complete STOMP frames could be decoded.

This chage modifies StompDecoder to return List<Message> after
exhaustively decoding all available STOMP frames from the input buffer.
Also an overloaded decode method allows passing in Map that will be
populated with any headers successfully parsed, which is useful for
"peeking" at the "content-length" header.

This change also adds a BufferingStompDecoder sub-class which buffers
any content left in the input buffer after parsing one or more STOMP
frames. This sub-class can also deal with fragmented messages,
re-assembling them and parsing as a whole message.

Issue: SPR-11527
2014-03-24 19:20:37 -04:00
Juergen Hoeller 465ca24ab2 DispatcherServlet logs request URI in encoded form only
Issue: SPR-11591
2014-03-24 23:26:05 +01:00
Juergen Hoeller 53352882ca Polishing 2014-03-24 22:58:33 +01:00
Juergen Hoeller dd7f54c3c0 Revised ResizableByteArrayOutputStream as an actual subclass of ByteArrayOutputStream, and consistently applied appropriate ByteArrayOutputStream initial capacities across the codebase
Issue: SPR-11594
2014-03-24 22:57:38 +01:00
Rossen Stoyanchev 05213c684c Give meaningful names to SprXxxTests in spring-test 2014-03-24 10:01:35 -04:00
Rossen Stoyanchev 9bda734e0a Improve method order in MockMvcRequestBuilders 2014-03-24 10:01:35 -04:00
Sebastien Deleuze 0b69a0ba4b Add URI based MockHttpServletRequestBuilder constructors
This commit adds new MockHttpServletRequestBuilder constructors
with an URI parameter in addition to the URL template + URL variables
existing ones.

It gives more control on how the URL is built, allowing for example to
use URL variables containing '/' character with proper encoding.

Issue: SPR-11441
2014-03-24 10:01:35 -04:00
Juergen Hoeller c10eeb414c Polishing 2014-03-24 14:37:08 +01:00
Juergen Hoeller ea5911f628 Upgraded to AspectJ 1.8.0 RC2 2014-03-24 14:36:25 +01:00
Sam Brannen 5ab0433543 Introduce Tiles version constants in Gradle build 2014-03-24 13:33:48 +01:00
Brian Clozel ae012ae6e2 ShallowEtagHeaderFilter use specified contentlength
Prior to this commit, the ShallowEtagHeaderFilter did not use the
content length given by the content generator to set the
ByteArrayOutputStream's buffer size.
This can lead to performance issues for large content since the buffer
grows as the content is being written.

This commit adds a new ByteArrayOutputStream variant called
ResizableByteArrayOutputStream. This implementation has public methods
for modifying the internal buffer size and does not synchronize on
buffer access.
This commit also make use of this new variant in
ShallowEtagHeaderFilter.

Issue: SPR-8271
2014-03-24 12:11:59 +01:00
Juergen Hoeller 4e24e079a8 Upgraded to Tiles 3.0.3 2014-03-24 11:52:42 +01:00
Juergen Hoeller 8b73c0affb Added ASM-based tests for custom scoping annotations
Issue: SPR-11574
2014-03-24 11:51:21 +01:00
Juergen Hoeller 7399723165 Introduced getFlashMapsMutex template method and optimized SessionFlashMapManager's locking
SessionFlashMapManager also clears the session attribute now when the given FlashMap List is empty.

Issue: SPR-11538
2014-03-24 11:16:56 +01:00
Juergen Hoeller 0af6e1bb1b MVC handler method detection ignores scoped targets in favor of proxies
Issue: SPR-11548
2014-03-24 11:02:03 +01:00
Rossen Stoyanchev 2f24bd24a8 Merge pull request #494 from rstoyanchev/doc-sockjs
Expand SockJS documentation
2014-03-23 23:15:03 -04:00
Rossen Stoyanchev f25b7df552 Document heartbeat support in SockJS 2014-03-23 23:13:13 -04:00
Rossen Stoyanchev b1a0b38d8f Document use of CORS headers in SockJS Service
Issue: SPR-11437
2014-03-23 22:52:14 -04:00
Rossen Stoyanchev 15188a8eee Document IE 8 and 9 related SockJS transport details
Issue: SPR-11496, SPR-11525
2014-03-23 22:52:13 -04:00
Rossen Stoyanchev d30cb17c91 Polish SockJS documentation 2014-03-23 22:51:31 -04:00
Rossen Stoyanchev 7af74b2475 Disable SockJS heartbeat if STOMP heartbeat is on 2014-03-23 02:12:57 -04:00
Rossen Stoyanchev 2c6d6b524d Adjust SockJS scheduler core pool size
Issue: SPR-11556
2014-03-23 01:04:30 -04:00
Rossen Stoyanchev 7651f83b4c Polish 2014-03-23 01:01:39 -04:00
Rossen Stoyanchev cbd5af3a03 Add CloseStatus to indicate unreliable session
When a send timeout is detected, the WebSocket session is now closed
with a custom close status that indicates so. This allows skipping
parts of the close logic that may cause further hanging.

Issue: SPR-11450
2014-03-23 00:51:33 -04:00
Rossen Stoyanchev 4028a3b0bc Remove synchronized keywords from SockJsSession impls
Before this change SockJsSession implementations of WebSocketSession
used synchronization around its method implementations protecting
internal state and ensuring only a single thread is sending messages
at a time.

A WebSocketSession is generally expected to be used from one thread
at a time and now that application messages are sent through
ConcurrentWebSocketSessionDecorator, there is no concern about
application messages sent from the different threads.

While there are some remaining concerns, those can be addressed
without using the synchronized keyword. This change removes it from
the methods of all SockJS session implementations.

Issue: SPR-11450
2014-03-22 22:59:48 -04:00
Rossen Stoyanchev ffac748f1c Improve ConcurrentWebSocketSessionDecorator
Before this change the decorator ensured that for a specific WebSocket
session only one thread at a time can send a message. Other threads
attempting to send would have their messages buffered and each time
that occurs, a check is also made to see if the buffer limit has been
reached or the send time limit has been exceeded and if so the session
is closed.

This change adds further protection to ensure only one thread at a time
can perform the session limit checks and attempt to close the session.
Furthermore if the session has timed out and become unresponsive,
attempts to close it may block yet another thread. Taking this into
consideration this change also ensures that state associated with the
session is cleaned first before an attempt is made to close the session.

Issue: SPR-11450
2014-03-22 22:59:39 -04:00
Rossen Stoyanchev 299be08268 Remove synchronized block around WebSocketSession.send
Since we now wrap the WebSocketSession with a concurrent decorator, the
synchronized keyword around message sending needed to be removed.

Issue: SPR-11586
2014-03-21 11:42:23 -04:00
Sam Brannen 796af90ba7 Polish ASM-based annotation processing
- AnnotationAttributesReadingVisitor no longer processes annotations
  from the java.lang.annotation package.

- Simplified logic in AnnotationReadingVisitorUtils
  getMergedAnnotationAttributes().

Issue: SPR-11574
2014-03-21 15:26:13 +01:00
Juergen Hoeller 90e3dbb0f5 BufferedImageHttpMessageConverter ignores empty MIME types
Issue: SPR-11581
2014-03-21 14:43:03 +01:00
Juergen Hoeller 3aff973d13 Javadoc: @ComponentScan is subject to @Conditional as well
Issue: SPR-11579
2014-03-21 14:32:57 +01:00
Rossen Stoyanchev 929e9ca401 Raise MessageConversionException in @Payload resolver
If a payload is present but conversion returns null (meaning no
converter knows how to convert), raise a MessageConversionException
that provides information about the type we were trying to convert
to and the message itself whose headers (namely content-type) contain
crucial information required to debug the problem.

Issue: SPR-11577
2014-03-21 08:59:12 -04:00
Brian Clozel 26309838ba Set custom handshakeHandler for XML sockjs config
Prior to this commit, configuring a custom handshakeHandler when setting
up a stomp-endpoint with SockJS would not be taken into account:

  <websocket:stomp-endpoint path="/foo">
    <websocket:handshake-handler ref="customHandler"/>
    <websocket:sockjs/>
  </websocket:stomp-endpoint>

This commit fixes this by creating and registering a
WebsocketTransportHandler (with this handshakeHandler) as a
transportHandler override for the SockJSService.

Issue: SPR-11568
2014-03-21 10:00:11 +01:00
Rossen Stoyanchev b7a974116e Add concurrent WebSocket session decorator (temp commit)
Issue: SPR-11586
2014-03-21 01:29:29 -04:00
Rossen Stoyanchev ac968e94ed Add getter for the length of a WebSocket message 2014-03-20 21:19:18 -04:00
Rossen Stoyanchev d4782647a4 Ensure default value of @Payload required is enforced
When no @Payload is provided, it is equivalent to @Payload with default
attribute values. Since the default value of required=true, then
an argument that's not annotated is required.
2014-03-20 19:44:19 -04:00
Stephane Nicoll 52c3f713bf Fix handling of required payload.
A payload that is required will now throw an appropriate exception
regardless of if a conversion is required or not.

isEmptyPayload now takes the payload instead of the message
so that both the original payload and the converted payload, if
necessary, share the same logic.

JSR-303 validation is now consistently applied.

Issue: SPR-11577
2014-03-20 16:43:33 -04:00
Stephane Nicoll 4cd818b9e4 Harmonize log configuration
Prior to this commit, the codebase was using a mix of log4j.xml
and log4j.properties for test-related logging configuration. This
can be an issue as log4j takes the xml variant first when looking
for a default bootstrap configuration.

In practice, some modules declaring the properties variant were
taking the xml variant configuration from another module.

The general structure of the configuration has also been
harmonized to provide a standard console output as well as an
easy way to enable trace logs for the current module.
2014-03-20 09:43:29 -07:00
Rossen Stoyanchev 10af128e96 Update thread pool settings in STOMP/WebSocket config
The clientInboundChannel and clientOutboundChannel now use twice
the number of available processors by default to accomodate for some
degree of blocking in task execution on average.

In practice these settings still need to be configured explicitly in
applications but these should serve as better default values than
the default values in ThreadPoolTaskExecutor.

Issue: SPR-11450
2014-03-20 00:45:37 -04:00
Sam Brannen 9cee70ff66 Polish ComponentScanParserTests and clean up warnings 2014-03-20 01:28:59 +01:00
Juergen Hoeller ad09f1b5ec Upgraded embedded ASM version to 5.0
Issue: SPR-11239
2014-03-20 01:06:22 +01:00
Sam Brannen 99cd2f6098 Support meta-annotation overrides in ASM processing
Prior to this commit, Spring supported meta-annotation attribute
overrides in custom composed annotations with reflection-based
annotation processing but not with ASM-based annotation processing.

This commit ensures that meta-annotation attribute overrides are
supported in AnnotationMetadataReadingVisitor.getAnnotationAttributes().

Issue: SPR-11574
2014-03-19 23:44:13 +01:00
Rossen Stoyanchev 1bab8a3916 Add session attributes to SimpMessageHeaderAccessor
This change exposes the WebSocketSession attributes through a message header.
The StompSubProtocolHandler adds this to incoming messages.
For now messaging handling  methods can access the map via @Header, e.g.:

@Header(StompHeaderAccessor.SESSION_ATTRIBUTES) Map<String, Object> attrs) {

Issue: SPR-11566
2014-03-19 13:45:40 -04:00
Rossen Stoyanchev 48b62e80d5 Rename handshakeAttributes to just attributes
Issue: SPR-11566
2014-03-19 12:25:08 -04:00
Rossen Stoyanchev 1fa4a7d34f Fix minor issue in STOMP broker relay 2014-03-19 10:35:48 -04:00
Rossen Stoyanchev 9552c82e2d Remove use of simple executor in WebSocket clients
Issue: SPR-11580
2014-03-19 10:24:48 -04:00
Sam Brannen 8aefcb9a55 Set DB_CLOSE_ON_EXIT=false in H2EmbeddedDbConfig
This commit sets the DB_CLOSE_ON_EXIT flag to false for embedded H2
databases loaded using H2EmbeddedDatabaseConfigurer (i.e., via Spring's
<jdbc:embedded-database /> XML namespace, EmbeddedDatabaseBuilder,
EmbeddedDatabaseFactory, and EmbeddedDatabaseFactoryBean).

Issue: SPR-11573
2014-03-19 01:22:46 +01:00
Sam Brannen dc6d67510d Improve configurability of EmbeddedDatabaseBuilder
This commit improves the configurability of EmbeddedDatabaseBuilder by
exposing the following new configuration methods.

 - setDataSourceFactory(DataSourceFactory)
 - addScripts(String...)
 - setScriptEncoding(String)
 - setSeparator(String)
 - setCommentPrefix(String)
 - setBlockCommentStartDelimiter(String)
 - setBlockCommentEndDelimiter(String)
 - continueOnError(boolean)
 - ignoreFailedDrops(boolean)

If more fine grained control over the configuration of the embedded
database is required, users are recommended to use
EmbeddedDatabaseFactory with a ResourceDatabasePopulator and forego use
of the builder.

Issue: SPR-11410
2014-03-18 23:56:31 +01:00
Sam Brannen 34fe252acd Polish Javadoc for embedded database support 2014-03-18 23:56:31 +01:00
Juergen Hoeller 373f07b1ff Polishing 2014-03-18 22:30:32 +01:00
Juergen Hoeller e0757e7ed6 Detect ControllerAdvice beans in ancestor contexts as well
Issue: SPR-11570
2014-03-18 22:29:50 +01:00
Sam Brannen b640b9fdfe Update TODOs for SPR-11574
Issue: SPR-11574
2014-03-18 18:33:26 +01:00
Sam Brannen 9ce0df89ff Support Class meta-annotation attributes with ASM
Prior to this commit, AnnotationAttributesReadingVisitor treated Class
annotation attributes as Strings instead of Classes. As a result,
look-ups for Class attributes in meta-annotations failed with an
IllegalArgumentException.

This commit fixes this issue by consistently treating Class attributes
as Classes in AnnotationAttributesReadingVisitor.

Issue: SPR-11557
2014-03-18 18:20:15 +01:00
Sam Brannen 42690a9a9e Overhaul Javadoc for embedded database support 2014-03-18 12:54:40 +01:00
Sam Brannen c61d62ef4b Improve DataSourceInitializer Javadoc and implementation 2014-03-18 12:54:02 +01:00
Sam Brannen 87e58a6d7b Improve Javadoc for DatabasePopulator 2014-03-18 12:52:59 +01:00
Rossen Stoyanchev df98490f0d Increase logging for spring-messaging tests
A temporary measure related to intermittent CI build server failures.
2014-03-17 22:32:01 -04:00
Sebastien Deleuze fb600857df Document locale convention in Tiles def file names
In Tiles v3 integration, underscores in filenames are
intended to identify the definition locale. This behavior
is now documented in order to avoid unexpected results
with filenames like tiles_definitions.xml.

This commit also updates Tiles v2 references to Tiles v3
in the Spring reference documentation.

Issue: SPR-11491
2014-03-17 21:37:37 -04:00
Sebastien Deleuze aac409c6cf Fix "Configuring the WebSocket Engine" documentation
This commit updates reference documentation in order
to specify that ServletServerContainerFactoryBean is for
server side use and WebSocketContainerFactoryBean
for client side use.

Issue: SPR-11565
2014-03-17 21:20:50 -04:00
Rossen Stoyanchev a372b683cd Use custom config read in ReactorTcpClient
Use a custom ConfigReader to enforce the use of SynchronousDispatcher
and no other dispatchers otherwise created by default. Avoids the
creation thread pools never to be used.
2014-03-17 21:13:14 -04:00
Juergen Hoeller 38e7c4776b Cache.get(key, type) should also work in case of null value found in cache
Issue: SPR-11567
2014-03-18 00:50:59 +01:00
Rossen Stoyanchev 57af56aeeb Improve logging in STOMP broker relay
Ignore DISCONNECT messages if already disconnected. This can occur if
the client explicitly sends a DISCONNECT frame and then closes the
socket quickly. The closing of the WebSocket sessions also sends a
DISCONNECT upstream to ensure the broker is aware.
2014-03-17 17:11:15 -04:00
Rossen Stoyanchev 918e21fd8f Upgrade to reactor 1.0.1.RELEASE 2014-03-17 17:10:53 -04:00
Sam Brannen 92eb99a5ab Favor ScriptException over SQLException
In ScriptUtils and related classes, SQLExceptions are now caught and
wrapped in ScriptExceptions wherever feasible.

Affected "throws" declarations have also been revised as appropriate.

Issue: SPR-11564
2014-03-17 16:05:09 +01:00
Juergen Hoeller cf290ab42a Extracted simple MethodInvokingBean as alternative to (and base class for) MethodInvokingFactoryBean
Issue: SPR-11196
2014-03-17 15:13:59 +01:00
Juergen Hoeller a8577da30c DeferredQueryInvocationHandler explicitly closes its EntityManager on garbage collection
Includes javadoc revision covering all supported EntityManager types as of JPA 2.1.

Issue: SPR-11451
2014-03-17 13:53:38 +01:00
Sam Brannen fbd25467c4 Introduce SQL script exception hierarchy
This commit continues the work began in SPR-9531 as follows.

 - ScriptException now extends DataAccessException.

 - DatabasePopulator.populate() now explicitly throws ScriptException.

 - Introduced UncategorizedScriptException.

 - DatabasePopulatorUtils.execute() now throws an
   UncategorizedScriptException instead of a
   DataAccessResourceFailureException.

Issue: SPR-11564
2014-03-17 12:26:32 +01:00
Rossen Stoyanchev f68bd5c8b2 Rename ReactorNettyTcpClient to ReactorTcpClient
Even though Netty is a required dependency of reactor-tcp at present,
there is no hard dependency in the spring-messaging Reactor-based
implementation.
2014-03-16 18:12:45 -04:00
Rossen Stoyanchev 2e13bf8b81 Refine Reactor-based TCP client implementation
Configure explicitly use of SynchronousDispatcher instead of the one
used otherwise by default (RingBufferDispatcher). As a result TCP
optations are now scoped to Netty's threads.

Remove Environment field. It is no longer required to shut it down
since we're now using SynchronousDispatcher by default.

Replace connection.in() with connection.consume() when composing
connection handling. The former creates a Stream for further composing,
e.g. via map(), filter() but all we need is to read a message.

Provide additional constructor that aceepts a pre-configured Reactor
TcpClient instance.

Issue: SPR-11531
2014-03-16 18:12:45 -04:00
Rossen Stoyanchev 6bcbb94aba Refine BrokerAvailabilityEvent behavior
Add accessor for brokerAvailable in AbstractBrokerMessageHandler
Ensure brokerAvailable is set even if eventPublisher is not
Add tests BrokerMessageHandlerTests

Turn off brokerAvailable when StompBrokerRelayMessageHandler stops
Actually stop message handling when brokerAvailable=false
Improve log messages

Issue: SPR-11563
2014-03-16 18:12:45 -04:00
Sam Brannen 14a8f19670 Add links to class-level Javadoc in JdbcTestUtils 2014-03-16 17:44:11 +01:00
Sam Brannen cae50c3a2d Polishing 2014-03-16 17:34:01 +01:00
Sam Brannen bb67cd4657 Fix regression for newline separators in SQL scripts
Changes made in conjunction with SPR-9531, introduced a regression with
regard to support for using a single newline character as the statement
separator within SQL scripts. Investigation of the cause of this issue
resulted in the discovery of another, similar issue: support for
multiple newlines as a statement separator has been broken for years
but has gone unnoticed until now.

The reason that both of these issues have gone unnoticed is a result of
the fact that the test suite only executes SQL script integration tests
against HSQL DB, and HSQL does not care if two statements occur on the
same line; whereas, the H2 database will throw an exception if multiple
statements are included on the same line when executing an update.

This commit addresses both of these issues and provides further
enhancements to Spring's SQL script support as follows.

 - ScriptUtils now properly checks if the supplied script contains the
   custom statement separator or default separator before falling back
   to the 'fallback' separator (i.e., newline).

 - Introduced FALLBACK_STATEMENT_SEPARATOR constant in ScriptUtils.

 - ScriptUtils.readScript() no longer omits empty lines from the input
   file since a statement separator string may in fact be composed of
   multiple newline characters.

 - Introduced overloaded variants of splitSqlScript() and
   executeSqlScript() in ScriptUtils with smaller argument lists for
   common use cases.

 - Extracted AbstractDatabasePopulatorTests from DatabasePopulatorTests
   and introduced concrete HsqlDatabasePopulatorTests and
   H2DatabasePopulatorTests subclasses for testing against HSQL and H2.

 - Split ScriptUtilsTests into ScriptUtilsUnitTests and
   ScriptUtilsIntegrationTests for faster builds.

Issue: SPR-11560
2014-03-16 16:41:08 +01:00
Sam Brannen e7b8a657b4 Add more tests for @ComponentScan as a meta-annotation
Issue: SPR-11557
2014-03-15 15:28:17 +01:00
Juergen Hoeller 189cd663c5 Polishing 2014-03-15 00:46:06 +01:00
Sam Brannen f1fbe85ff1 Investigate issue with @ComponentScan as meta-annotation
This commit introduces unit and integration tests that attempt to
reproduce the issue claimed by the reporter in SPR-11557. However, the
tests pass without any problems.

Issue: SPR-11557
2014-03-15 00:04:53 +01:00
Sam Brannen 3d506eb033 Clean up ConfigurationClassPostProcessorTests 2014-03-14 22:34:11 +01:00
Juergen Hoeller 99ea429fd7 Added specific unit test for scoped-proxy target not being an autowire candidate
Issue: SPR-11548
2014-03-14 20:40:24 +01:00
Juergen Hoeller 5308b3e358 Revised naming for prototype inner beans to avoid excessive unique name calculation
Restored original singleton-only adaptInnerBeanName behavior, avoiding endless unique name calculation for every single prototype instance. Non-named inner BeanDefinition objects now suffixed with an identity hex code analogous to non-named XML bean definitions, largely avoiding naming collisions to begin with. After SPR-11246, post-processors can deal with unstable classes per bean name, so occasional collisions aren't a hard problem anymore.

Issue: SPR-11545
2014-03-14 20:38:09 +01:00
Sam Brannen 9dcd03d862 Clean up imports and warnings 2014-03-14 17:34:21 +01:00
Juergen Hoeller 5ff1c696c8 Check raw Type objects, not ResolvableType instances, during isAssignableFrom recursion
Issue: SPR-11522
2014-03-14 00:45:40 +01:00
Juergen Hoeller 791f58e6be Polishing 2014-03-13 17:31:39 +01:00
Juergen Hoeller 4744180d3d NumberUtils reports overflow when converting from BigInteger/BigDecimal to Long
Issue: SPR-11434
2014-03-13 17:03:55 +01:00
Sam Brannen 01b2f67f11 Introduce constructors in ResourceDatabasePopulator
Issue: SPR-9531
2014-03-13 13:45:05 +01:00
Sam Brannen a006ca2542 Remove trailing whitespace 2014-03-13 12:21:32 +01:00
Sam Brannen 7853e74e78 Merge pull request #485 from cbaldwin74/SPR-9531
* SPR-9531:
  Refactor SQL script support
  Support multi-line comments in SQL scripts
2014-03-13 12:05:49 +01:00
Sam Brannen 2bfd6ddcf4 Refactor SQL script support
This commit continues the work in the previous commit as follows:

 - Introduced an exception hierarchy for exceptions related to SQL
   scripts, with ScriptException as the base.

 - CannotReadScriptException and ScriptStatementFailedException now
   extend ScriptException.

 - Introduced ScriptParseException, used by ScriptUtils.splitSqlScript().

 - DatabasePopulatorUtils.execute() now explicitly throws a
   DataAccessException.

 - Polished Javadoc in ResourceDatabasePopulator.

 - Overhauled Javadoc in ScriptUtils and documented all constants.

 - Added missing @author tags for original authors in ScriptUtils and
   ScriptUtilsTests.

 - ScriptUtils.splitSqlScript() now asserts preconditions.

 - Deleted superfluous methods in ScriptUtils and changed method
   visibility to private or package private as appropriate.

 - Deleted the ScriptStatementExecutor introduced in the previous
   commit; ScriptUtils.executeSqlScript() now accepts a JDBC Connection;
   JdbcTestUtils, AbstractTransactionalJUnit4SpringContextTests, and
   AbstractTransactionalTestNGSpringContextTests now use
   DatabasePopulatorUtils to execute a ResourceDatabasePopulator instead
   of executing a script directly via ScriptUtils.

 - Introduced JdbcTestUtilsIntegrationTests.

Issue: SPR-9531
2014-03-13 12:00:01 +01:00
cbaldwin74 e5c17560db Support multi-line comments in SQL scripts
Prior to this commit neither ResourceDatabasePopulator nor
JdbcTestUtils properly supported multi-line comments (e.g., /* ... */).
Secondarily there has developed a significant amount of code
duplication in these two classes that has led to maintenance issues
over the years.

This commit addresses these issues as follows:

 - Common code has been extracted from ResourceDatabasePopulator and
   JdbcTestUtils and moved to a new ScriptUtils class in the
   spring-jdbc module.

 - Relevant test cases have been migrated from JdbcTestUtilsTests to
   ScriptUtilsTests.

 - ScriptUtils.splitSqlScript() has been modified to ignore multi-line
   comments in scripts during processing.

 - ResourceDatabasePopulator supports configuration of the start and end
   delimiters for multi-line (block) comments.

 - A new test case was added to ScriptUtilsTests for the new multi-line
   comment support.

Issue: SPR-9531
2014-03-13 10:51:08 +01:00
Rossen Stoyanchev 6b31074e4a Add HTTP series check shortcut methods to HttpStatus
Issue: SPR-11424
2014-03-12 17:04:16 -04:00
Rossen Stoyanchev 6a4a2ec6a4 Fix expected and actual argument order
Issue: SPR-11424
2014-03-12 16:52:52 -04:00
Rossen Stoyanchev 3474afb165 Improve suffix pattern check
After this change dots inside URI variables in a request mapping
pattern are ignored and no longer considered an indication that
the pattern contains a suffix itself.

Issue: SPR-11532
2014-03-12 16:42:16 -04:00
Juergen Hoeller 4d3ca4319e Polishing 2014-03-11 22:09:46 +01:00
Brian Clozel 8b2b165777 Fix "relay-port" XSD type in spring-websocket.xsd
Prior to this commit, the `relay-port` attribute of the
`<websocket:stomp-broker-relay />` tag was of type `xsd:int`.
This prevents developers from using `PropertyPlaceholderConfigurer`,
even though this configuration key is a good candidate for such use
(this value depends on prod/staging/etc environment).

This commit changes that type to `xsd:string`.

Issue: SPR-11537
2014-03-11 20:33:13 +01:00
Juergen Hoeller 658a44a620 Upgraded to Apache HttpClient 4.3.3 and Jetty 9.1.3 2014-03-11 12:57:27 +01:00
Juergen Hoeller 27cacf0672 SpEL property-not-found message hints at non-public method/field
Issue: SPR-11535
(cherry picked from commit eeb82c4)
2014-03-11 11:20:29 +01:00
Rossen Stoyanchev 13af188bdc Handle invalid STOMP content-length header value
After this change if a content-length header is provided but is less
than 0 or cannot be parsed as a number, it is ignored and the body
is read sequentially, i.e. until we reach a null byte terminator.

This provides better protection against clients that may set the
content-length header in error.

Issue: SPR-11528
2014-03-10 22:07:39 -04:00
Rossen Stoyanchev cff23b84ae Add messages for number of active sessions/connections
Issue: SPR-11531
2014-03-10 16:58:02 -04:00
Rossen Stoyanchev a473d46e1c Tighten connection management in STOMP broker relay
Fix NPE exception when closing TcpConnection

Ensure a ConnectionHandler is cleared when a TcpConnection is closed
(at the same time), logging an exception if the closing fails.

Improve error messages.

Issue: SPR-11531
2014-03-10 16:46:13 -04:00
Juergen Hoeller bbcb1837c5 Polishing
Issue: SPR-11442
2014-03-10 18:31:03 +01:00
Juergen Hoeller 264d7b9c98 Improved documentation on how to convert collections with ConversionService
Issue: SPR-11432
2014-03-10 18:18:29 +01:00
Stephane Nicoll 7a6ec69523 Fix custom config with older HttpClient
Since HttpClient 4.3, custom configuration such as the connection
timeout and the socket timeout are set in a RequestConfig object
stored in the HttpContext.

Unfortunately, older HttpClients are not supporting this
infrastructure and new clients throw an exception when the
deprecated API is used.

This commit detects if the client is an "old" implementation and
set the configuration through the deprecated means to restore
full backward compatibility with these features.

Issue: SPR-11442
2014-03-10 17:42:09 +01:00
Juergen Hoeller bea94d5302 CollectionToCollectionConverter avoids collection copy for untyped collection when simply returning source anyway
Also uses addAll instead of iteration over untyped collection now, supporting optimized addAll in target collection type, and avoids repeated getElementTypeDescriptor calls.

Issue: SPR-11479
2014-03-10 15:59:19 +01:00
Juergen Hoeller 40b81fcc3e SPR11348 test should use LinkedHashSet since it relies on insertion order of elements 2014-03-10 13:33:56 +01:00
Sam Brannen 241682c117 Update author list in reference manual 2014-03-10 12:31:00 +01:00
Sam Brannen b364599278 Update links to Spring JIRA server 2014-03-10 12:26:29 +01:00
Sam Brannen 220267b830 Update copyright date in reference manual 2014-03-10 12:22:52 +01:00
Stephane Nicoll 542db72ffd Add first draft of IDEA code formatting
This commit provides a first attempt at defining a standard code
formatting scheme for the Spring Framework in Intellij IDEA.

These are the major changes compared to standard settings:

* default indent option to use tab character instead of space for
  all languages
* one space before the left brace of an array initializer
* keep when reformating: multiple expressions in one line,
  simple blocks in one line
* method declaration parameters: do not align when multiline
* else, catch and finally on new line
* keep one space before } (solely use to keep the space between the
  end of the last method and the end of the class)
* minimum blank line after class header 0 (instead of 1)
* Disabled Javadoc formatting
* class count to trigger static import to 50 (to prevent
  import org.foo.*; instead of listing the classes of org.foo)
* changed the import sequence to import in the following order:
  static imports, java.*, javax.*, others, org.springframework.*. Each
  sequence is separated by a space
2014-03-10 11:43:19 +01:00
Sam Brannen 1d57a15e40 Delete unused imports in spring-test 2014-03-07 18:27:34 +01:00
Sam Brannen 1ade9b5433 Polish various test classes 2014-03-07 18:06:30 +01:00
Sam Brannen e865d63c29 Ensure Gradle does not execute inner classes as tests 2014-03-07 17:31:44 +01:00
Juergen Hoeller bcde955ec9 Ignore placeholder resolution failure as well in case of ignoreResourceNotFound=true
Issue: SPR-11524
2014-03-07 13:39:01 +01:00
Juergen Hoeller 3dfa7e9ac0 Avoid stack overflow in case of circular type reference
Issue: SPR-11522
2014-03-07 00:08:15 +01:00
Juergen Hoeller 93c8b7ab04 DefaultListableBeanFactory only puts 'cache-safe' Class keys into its by-type cache
Issue: SPR-11520
2014-03-06 22:41:38 +01:00
Rossen Stoyanchev 07959cb3f7 Merge pull request #484 from sdeleuze/SPR-11504 2014-03-06 12:29:22 -05:00
Rossen Stoyanchev 0036d9a5c9 Polish 2014-03-06 12:28:06 -05:00
Sebastien Deleuze 2f8bc6eec1 Decode target parameter names prior to saving a FlashMap
In addition to the target parameter values (SPR-9657), the target
parameter names must also be decoded to be able to match
them to the parameter names of incoming requests.

Issue: SPR-11504
2014-03-06 11:56:28 -05:00
Stephane Nicoll 519799e1cf Fix double SPeL evaluation of parameter
When a node of an SPeL expression was a call to a bean referenced
 in a method argument, the expression was resolved twice.

 The resolved arguments are now specified to MethodValueRef instead
 of resolving the arguments again in the constructor

 Issue: SPR-11445
2014-03-06 15:11:22 +01:00
Sam Brannen c8f2e07182 Clean up test warnings that show up in Gradle console 2014-03-06 14:50:46 +01:00
Sam Brannen cb59d43a5f Fix typos in Javadoc in AssertThrows 2014-03-06 14:40:41 +01:00
Juergen Hoeller 213d9c4a51 Consistent dependencies on official JTA 1.2 and JMS 1.1 API jars 2014-03-06 14:19:48 +01:00
Juergen Hoeller 3080ff3890 Polishing 2014-03-06 14:18:26 +01:00
Juergen Hoeller 7972b31118 SpringBeanELResolver's setValue should not throw PropertyNotWritableException if provided value is identical to current bean instance
Issue: SPR-11502
2014-03-06 14:17:54 +01:00
Juergen Hoeller 793cab4f80 Allow generics-based injection in case of nested unresolved type variable
Issue: SPR-11471
2014-03-06 14:13:33 +01:00
Rossen Stoyanchev 49d7bda722 Improve CORS handling in AbstractSockJsService
After this change, AbstractSockJsService does not add CORS headers if
the response already contains an "Access-Control-Allow-Origin" header.
Essentially it backs off assuming CORS headers are handled centrally
e.g. through a Filter.

In order to support this, the ServletServerHttpResponse now returns an
instance of HttpHeaders that also provides access to headers already
present in the HttpServletResponse.

Issue: SPR-11443
2014-03-05 21:06:46 -05:00
Sam Brannen cf3b2b1a4d Simplify test includes & excludes in Gradle build
This commit aligns our include and exclude filters for test classes
with Gradle's standard patterns. Specifically, our patterns now end
with ".class" instead of ".*".

The aforementioned change makes the exclusion of inner classes
unnecessary. Thus, patterns for test classes ending with "TestCase" or
"TestSuite" have been deleted.

Furthermore, the include and exclude patterns previously used in the
spring-test module made it impossible for the
FailingBeforeAndAfterMethodsTests class in the 'testng' package to ever
be executed by the build. This has been addressed by renaming our JUnit
and TestNG variants of FailingBeforeAndAfterMethodsTests and moving the
TestNG variant into the 'junit' package so that it can be picked with
our standard include pattern for JUnit-based tests.
2014-03-06 00:06:50 +01:00
Juergen Hoeller d30128396e Upgraded to Hibernate 4.2.10 2014-03-05 22:42:03 +01:00
Juergen Hoeller 2cdc066daf Relaxed statement on early validation of bean references
Issue: SPR-11495
2014-03-05 22:41:26 +01:00
Juergen Hoeller 2a2816dfc3 Restored proper handling of varargs in case of unresolvable type variable
Fixed through falling back to the raw parameter type in the TypeDescriptor(MethodParameter) constructor, properly detecting the vararg array even in case of an unresolvable type variable, and through restoring getElementTypeDescriptor's original behavior for arrays, i.e. always returning a non-null descriptor.

Issue: SPR-11494
2014-03-05 22:36:12 +01:00
Rossen Stoyanchev 34924810fe Remove field no longer used after previous commit
Issue: SPR-11516
2014-03-05 14:50:16 -05:00
Rossen Stoyanchev 74de35df1e Refactor async result handling in Spring MVC Test
This change removes the use of a CountDownLatch to wait for the
asynchronously computed controller method return value. Instead we
check in a loop every 200 milliseconds if the result has been set.
If the result is not set within the specified amount of time to wait
an IllegalStateException is raised.

Additional changes:
 - Use AtomicReference to hold the async result
 - Remove @Ignore annotations on AsyncTests methods
 - Remove checks for the presence of Servlet 3

Issue: SPR-11516
2014-03-05 12:55:39 -05:00
Juergen Hoeller e50cff47c1 KeyGenerators should not return a plain array parameter as raw key but rather always handle that case in a deepHashCode fashion
Issue: SPR-11505
2014-03-05 17:37:09 +01:00
Rossen Stoyanchev a434903a2a Adjust log level in LoggingWebSocketHandlerDecorator 2014-03-05 11:13:41 -05:00
Stephane Nicoll 9325a99bf0 Merge pull request #462 from snicoll/cache-tx-tests
* cache-tx-tests:
  Add tests for TransactionAwareCacheDecorator
2014-03-05 16:48:35 +01:00
Stephane Nicoll 45406aa19b Add tests for TransactionAwareCacheDecorator
This commit adds tests for TransactionAwareCacheDecorator. In
particular, the put/evict behaviour when the operation is invoked in
the course of Spring-managed transaction.
2014-03-05 16:48:20 +01:00
Juergen Hoeller ad317774fb instantiateUsingFactoryMethod avoids NPE and reports argument types in case of explicitArgs and resolved generic arguments as well
Issue: SPR-11517
2014-03-05 16:16:29 +01:00
Sam Brannen 9891bdc7b4 Clean up "abstract" test issues
- Deleted empty AbstractWebSocketClientTests class.

 - AbstractServletHandlerMethodTests and AbstractHttpRequestTests are
   now actually declared as abstract.

 - The following classes are not abstract but currently have an
   "Abstract" prefix and therefore get ignored by the Gradle build.
   This commit renames each of these by deleting the "Abstract" prefix.

   - AbstractFlashMapManagerTests
   - AbstractMappingContentNegotiationStrategyTests
   - AbstractSockJsServiceTests
   - AbstractWebSocketHandlerRegistrationTests
2014-03-05 12:41:26 +01:00
Sam Brannen b42f258c54 Use unmodifiable set in AbstractSockJsSession 2014-03-05 11:04:06 +01:00
Rossen Stoyanchev 705efc5bdf Fix timing issue with obtaining async result
Issue: SPR-11516
2014-03-04 21:38:42 -05:00
Stephane Nicoll c146be2eb7 Merge pull request #477 from candrews/patch-1
* patch-1:
  Fix SimpleKey equality with array argument
2014-03-04 14:24:03 +01:00
Craig Andrews 6d8f3a0a20 Fix SimpleKey equality with array argument
Prior to this commit, an array argument was not handled properly in
SimpleKey#equals and SimpleKey#hashCode. As a result, two method
invocations with the same array argument lead to two different keys
and therefore two different entries in the cache.

This commit uses deepEquals and deepHashCode to properly handle
methods that have arguments that are array types.

Issue: SPR-11505
2014-03-04 14:18:11 +01:00
Juergen Hoeller 9b771573ec Log4jWebConfigurer does not try to parse empty "log4jRefreshInterval" context-param
Issue: SPR-11507
2014-03-04 13:31:59 +01:00
Juergen Hoeller f3884084f2 Optimized DefaultResourceLoader's getResource implementation for "/..." paths, not relying on URL parsing exceptions for such a common case anymore
Issue: SPR-8283
2014-03-04 13:31:51 +01:00
Juergen Hoeller cb41f42791 AbstractApplicationEventMulticaster filters listeners against their type first, avoiding eager retrieval of listener instances for non-matching events
Issue: SPR-11501
2014-03-04 13:31:40 +01:00
Sam Brannen fa44224430 Aggregate JUnit and TestNG test reports
Prior to this commit, the test results for JUnit tests overwrote the
results for TestNG tests in the HTML test report generated by the
Gradle build.

This commit addresses this problem by introducing a new
'aggregateTestReports' task in the spring-test module and making the
'check' task depend on it.

To see aggregated reports in the spring-test module, execute either
`gradle build` or `gradle check`. Executing `gradle test` alone will
not trigger test report aggregation.

Issue: SPR-11509
2014-03-04 13:18:42 +01:00
Sam Brannen a60b34fd9e Merge pull request #476 from platan/master
Update MockRestServiceServer example in reference manual
2014-03-03 22:46:11 +01:00
Marcin Mielnicki 7cf5e3a508 Outdated code example correction in section 10.3.6 2014-03-03 22:20:28 +01:00
Brian Clozel 53017da0c3 Update reference documentation for SPR-11486
Issue: SPR-11486
2014-03-03 12:13:17 +01:00
Stephane Nicoll 035d9d5af0 Clarify exception handling in converter
Issue: SPR-11500
2014-03-03 10:02:39 +01:00
Sam Brannen 8f3a897502 Polish AbstractSockJsSession 2014-03-02 16:21:48 +01:00
Rossen Stoyanchev 4238299661 Add smart logging for disconnected SockJS clients
The Servlet API does not provide notifications when a client
disconnects, see see https://java.net/jira/browse/SERVLET_SPEC-44.
Therefore network IO failures may occur simply because a client has
gone away. Before this change that could fill logs with unnecessary
stack traces.

After this change we make a best effort to identify such network
failures, on a per-server basis (tested with Jetty, Tomcat, Glassfish,
and WildFly), and log them under a separate log category.

A simple one-line message is logged at DEBUG level (i.e. no stack trace)
while a full stack trace is shown at TRACE level.

Issue: SPR-11438
2014-03-01 14:46:44 -05:00
Sam Brannen 5d4ed4efe5 Fix DocBook to AsciiDoc conversion errors
- "__ `text`__" --> "__`text`__"

 - "`text` s" --> "`text`s"
2014-02-28 22:31:06 +01:00
Sam Brannen 1d47034736 Merge pull request #466 from olivergierke/SPR-11459
* SPR-11459:
  Update ref. manual to favor constructor injection
2014-02-28 22:00:22 +01:00
Oliver Gierke 74969a4794 Update ref. manual to favor constructor injection
The breakout box named "Constructor-based or setter-based DI?" in the
reference manual currently recommends the use of setter injection.

This commit refines this text to align with current best practices and
now favors constructor injection over setter injection.

Issue: SPR-11459
2014-02-28 21:53:54 +01:00
Juergen Hoeller 9af7d2646b Added documentation on how to set up JSR-303 method validation
Also removed outdated Struts references and made use of 'javadocs' term consistent.

Issue: SPR-11473
2014-02-28 19:02:18 +01:00
Juergen Hoeller 473061ec1e Added explicit note on thread safety to JdbcTemplate variants
Issue: SPR-11478
2014-02-28 19:00:31 +01:00
Rossen Stoyanchev c553d681f1 Add Servlet 3.1 methods to mock request
Issue: SPR-11492
2014-02-28 12:28:17 -05:00
Rossen Stoyanchev 3786993eb0 Merge pull request #474 from sdeleuze/SPR-11488 2014-02-28 11:55:57 -05:00
Rossen Stoyanchev c4000727ef Move customize(Un)Marshaller methods to abstract class
Issue: SPR-11488
2014-02-28 11:54:34 -05:00
Sebastien Deleuze 45be8c0692 Add marshalling hooks in Jaxb2RootElementHttpMessageConverter
Allow Jaxb2RootElementHttpMessageConverter subclasses to customize
the {@link Marshaller} and the {@link Unmarshaller} created by the
message converter.

Issue: SPR-11488
2014-02-28 11:48:31 -05:00
Sam Brannen 474142a862 Update link to Pro Git in CONTRIBUTING page 2014-02-28 17:43:18 +01:00
Sam Brannen 3a758a8c60 Update link to Pro Git in CONTRIBUTING page 2014-02-28 17:31:18 +01:00
Brian Clozel b22ae598ca update org name in links
SpringSource github org name changed to spring-projects.
2014-02-28 17:21:54 +01:00
Sam Brannen 5637890661 Link to @SpringCentral in README 2014-02-28 17:18:38 +01:00
Sam Brannen 57ecb9f307 Polish formatting and update links in README 2014-02-28 16:05:49 +01:00
Rossen Stoyanchev 035bac025a Use unique names when auto-registering Filters
AbstractDispatcherServletInitializer now adds a unique suffix to a
filter name if it fails to register it.

Issue: SPR-11493
2014-02-28 09:56:46 -05:00
Rossen Stoyanchev 8b24f99487 Update CONTRIBUTING.md 2014-02-28 09:50:31 -05:00
Brian Clozel fc05df0f14 Expose path matching settings in MVC Java config
Prior to this commit, one had to provide her own
RequestMappingHandlerMapping instance (i.e extend
WebMvcConfigurationSupport and override the requestMappingHandlerMapping
method) in order to customize path matching properties on that bean.

Since SPR-10163, XML config users can do that using the
<mvc:path-matching/> XML tag. This commit adds the same feature to MVC
Java config with a PathMatchConfigurer.

Issue: SPR-11486
2014-02-28 15:50:01 +01:00
Rossen Stoyanchev 1c90bf5e4f Update CONTRIBUTING.md 2014-02-28 09:49:17 -05:00
Sam Brannen d108db8a79 Polish CONTRIBUTING page 2014-02-28 15:40:13 +01:00
Sam Brannen 2edff2135f Polish Javadoc for DefaultContentTypeResolver 2014-02-28 15:19:35 +01:00
Juergen Hoeller ac61b13a7c AnnotatedElementUtils wraps unexpected exceptions with descriptive IllegalStateException
Issue: SPR-10441
2014-02-28 14:17:37 +01:00
Juergen Hoeller 1763bfbad0 Fixed content length check in XmlValidationModeDetector
Issue: SPR-11477
2014-02-28 14:00:32 +01:00
Juergen Hoeller bc5af2c6b6 Upgraded to Hibernate 4.2.9 2014-02-28 14:00:00 +01:00
Rossen Stoyanchev 6016536055 Remove ContentTypeResolver from composite converter
Before this change CompositeMessageConverter had a ContentTypeResolver
field that was in turn set on all contained converters.

After this change that field is removed and effectively
CompositeMessageConverter is a simple container of other converters.
Each converter in turn must have been configured with a
ContentTypeResolver.

Doing so means it is less likely to have unexpected consequences when
configuring converters, the ContentTypeResolver set in the composite
converter overriding the one configured in a contained converter.

Also commit 676ce6 added default ContentTypeResolver initialization
to AbstractMessageConverter, which ensures that converters are still
straight forward to configure.

Issue: SPR-11462
2014-02-27 21:41:35 -05:00
Rossen Stoyanchev 0da1eefd74 Add default ContentTypeResolver initialization
Previously AbstractMessageConverter did not have a ContentTypeResolver
configured by default. However the Java config and XML namespace in
spring-messaging and spring-websocket always configured one.

This change ensures every AbstractMessageConverter is configured with an
instance of DefaultContentTypeResolver by default. This makes sense since
all the resolver does is make an attempt to find a content type to use
for matching. If it can't it returns null and it's up to the converter
to decide whether it can convert or not.

Issue: SPR-11462
2014-02-27 21:40:53 -05:00
Rossen Stoyanchev 801237aec1 Add getMatchingPatterns method to Patterns condition
Issue: SPR-11484
2014-02-27 16:27:40 -05:00
Rossen Stoyanchev 56476cdd5f Add strictContentTypeMatching converter option
AbstractMessageConverter now supports a strictContentTypeMatching mode
in which the content type of a message must be resolved to a (non-null)
value that matches one of the configured supported MIME types in order
for the converter to be used.

Issue: SPR-11463
2014-02-27 15:43:54 -05:00
Sebastien Deleuze 2b69c1f15b Support String contentType headers in spring-messaging
After this change DefaultContentTypeResolver supports String-based
"contentType" header values in addition to MimeType-based.

Issue: SPR-11461
2014-02-27 12:00:50 -05:00
Brian Clozel 11c41993f1 Update documentation with coding guidelines
This commit:
* adds a reference to the Spring Code Style wiki page in the main
CONTRIBUTING document
* updates the link to the Spring team in README
* adds a note regarding Intellij IDEA 13 issues
2014-02-27 11:16:47 +01:00
Sam Brannen 0637864b39 Ensure AnnotationUtils is compatible with Java 6
The previous commit introduced a dependency on
Class.getDeclaredAnnotation() which is a Java 8 API.

This commit refactors AnnotationUtils.findAnnotation(Class, Class, Set)
to use Class.getAnnotation() in conjunction with
isAnnotationDeclaredLocally() in order to achieve the same desired
behavior.

Issue: SPR-11475
2014-02-26 17:51:26 +01:00
Sam Brannen 0f5a27c354 Merge changes from sbrannen/SPR-11475
* SPR-11475:
  Favor 'local' annotations over inherited ones
2014-02-26 16:09:29 +01:00
Sam Brannen 1d30bf83a0 Favor 'local' annotations over inherited ones
Prior to this commit, the implementations of findAnnotation() in
AnnotationUtils and getAnnotationAttributes() in AnnotatedElementUtils
favored inherited annotations and inherited composed annotations over
composed annotations that are declared closer to the starting class
passed to these methods.

This commit addresses this issue as follows:

- Refactored AnnotationUtils to use getDeclaredAnnotation() and
  getDeclaredAnnotations() instead of getAnnotation() and
  getAnnotations() where appropriate.

- AnnotatedElementUtils.doProcess() supports a traverseClassHierarchy
  flag to control whether the class hierarchy should be traversed,
  using getDeclaredAnnotations() instead of getAnnotations() if the
  flag is true.

- Overhauled Javadoc in AnnotatedElementUtils.

Issue: SPR-11475
2014-02-26 16:06:42 +01:00
Juergen Hoeller 0616cbccd6 Upgraded JSP build dependency to 2.2 2014-02-26 15:44:50 +01:00
Sam Brannen fbdebc1bd6 Clean up warnings that show up in Gradle build 2014-02-26 14:05:26 +01:00
Sam Brannen 019d29c991 Delete work-around for Ant 1.8 in Gradle build
Ant 1.9.2 is packaged with Gradle since release 1.10. Since the Spring
Framework build now uses Gradle 1.11, there is no longer a need for the
"javac1.7" build compiler work-around for the spring-oxm module.
2014-02-26 13:58:04 +01:00
Sam Brannen 1ac08e4a1b Polish Javadoc for ConfigurationClassParser 2014-02-26 02:22:32 +01:00
Sam Brannen 979c483384 Do not inspect meta-annotations on Java annotations
This commit introduces a new isInJavaLangAnnotationPackage(Annotation)
method in AnnotationUtils. This method is now used in AnnotationUtils,
AnnotatedElementUtils, and MetaAnnotationUtils to ensure that search
algorithms do no search for meta-annotations on annotations in the
"java.lang.annotation" package.

The following are some empirical results from this change:

- The number of times that the findAnnotation(Class,Class,Set) method in
  AnnotationUtils is recursively invoked while executing
  AnnotationUtilsTests drops from 51 to 29.

- The number of times that the process(AnnotatedElement) method in
  AnnotationUtils.AnnotationCollector is recursively invoked while
  executing AnnotationUtilsTests.getRepeatableFromMethod() drops
  from 16 to 2.

- The number of times that the doProcess() method in
  AnnotatedElementUtils is recursively invoked while executing the
  "getAnnotationAttributes() On MetaCycleAnnotatedClass with missing
  target meta-annotation" test in AnnotatedElementUtilsTests drops
  from 23 to 5.

- The number of times that the findAnnotationDescriptor(Class,Set,Class)
  method in MetaAnnotationUtils is recursively invoked while executing
  the "findAnnotationDescriptor() on MetaCycleAnnotatedClass with
  missing target meta-annotation" test in MetaAnnotationUtilsTests drops
  from 16 to 8.

Issue: SPR-11483
2014-02-25 21:57:35 +01:00
Rossen Stoyanchev 651e0a44fb Update documentation
Clarify ability to use @MessageMapping methods on both @Controller as
well as @RestController.

Add section on configuring connections (including credentials) to the
message broker and clarify the use of the login/passcode headerers of
the STOMP CONNECT frame.

Add note on when to add the reactor-tcp dependency.

Issue: SPR-11464, SPR-11436, SPR-11449
2014-02-25 11:31:13 -05:00
Sam Brannen ce0d916492 Fix 'method' typo in @PropertySources 2014-02-25 15:56:39 +01:00
Sam Brannen 39eb7442fc Merge changes from sbrannen/SPR-11455
* SPR-11455:
  Always supply test class to ContextLoaders in TCF
2014-02-25 15:36:17 +01:00
Sam Brannen 78b69f5d77 Always supply test class to ContextLoaders in TCF
Prior to this commit, the following methods in ContextLoaderUtils
treated a composed @ContextConfiguration annotation (i.e., a custom
annotation that is meta-annotated with @ContextConfiguration) as the
"declaring class" instead of the actual test class.

- resolveContextConfigurationAttributes()
- resolveContextHierarchyAttributes()

As a consequence, if @ContextConfiguration is used as a
meta-annotation, the meta-annotated class is stored as the
"declaringClass" in ContextConfigurationAttributes. Thus, when a
ContextLoader (or SmartContextLoader) attempts to detect default
resource locations or configuration classes, it does so for the
composed annotation class instead of for the declaring test class.

This commit ensures that ContextLoaders are supplied the declaring test
class instead of the composed annotation class in such use cases.

Issue: SPR-11455
2014-02-25 15:27:31 +01:00
Sam Brannen 76cc6db5fc Upgrade to TestNG 6.8.8
Issue: SPR-11482
2014-02-25 15:26:16 +01:00
Rossen Stoyanchev b727cdb120 Adjust ActiveMQ settings in integration tests
Before this change tests on the CI server showed the following message:

Store limit is 102400 mb, whilst the data directory:
/opt/.../KahaDB only has 74810 mb of usable space

This change turns off store persistence and also explicitly sets the
limit on memory usage.
2014-02-24 17:07:34 -05:00
Phillip Webb 2ec4c00068 Merge pull request #468 from wilkinsona/jasperreports
* jasperreports:
  Make version of JasperReports consistent
2014-02-24 10:56:59 -08:00
Andy Wilkinson 7c4fbec1cd Make version of JasperReports consistent
Ensure that context-support and webmvc depend upon the same version
of JasperReports
2014-02-24 10:56:14 -08:00
Phillip Webb cd6d234244 Merge pull request #469 from petrukhnov/patch-1
* patch-1:
  Removed repeated 'multiple' word in comment
2014-02-24 10:49:05 -08:00
Konstantin Petrukhnov ccb7737716 Removed repeated 'multiple' word in comment 2014-02-24 10:48:42 -08:00
Sam Brannen 90b938aa8f Verify status quo when searching for non-inherited composed annotations
Issue: SPR-11475
2014-02-24 00:13:47 +01:00
Sam Brannen f8950960f2 Support arbitrary meta-annotation levels in the TCF
Prior to this commit, the findAnnotationDescriptor() and
findAnnotationDescriptorForTypes() methods in MetaAnnotationUtils only
supported a single level of meta-annotations. In particular, this kept
the following annotations from being used as meta-annotations on
meta-annotations:

- @ContextConfiguration
- @ContextHierarchy
- @ActiveProfiles
- @TestExecutionListeners

This commit alters the search algorithms used in MetaAnnotationUtils so
that arbitrary levels of meta-annotations are now supported for the
aforementioned test-related annotations.

Issue: SPR-11470
2014-02-23 01:05:15 +01:00
Sam Brannen 2c8f25a14c Delete call to System.err in AbstractContextLoaderUtilsTests 2014-02-23 00:28:00 +01:00
Sam Brannen aa3e250ab6 @Ignore PrintingResultHandlerTests 2014-02-23 00:24:24 +01:00
Sam Brannen 3c511f00cc Simplify MetaAnnotationUtilsTests 2014-02-22 18:48:55 +01:00
Sam Brannen d9a2b3c2ba Deleted unused code in ContextLoaderUtilsActiveProfilesTests 2014-02-22 18:09:59 +01:00
Sam Brannen dc6eaad2e9 Update copyright date in ContextLoaderUtils 2014-02-22 18:06:37 +01:00
Sam Brannen 5f7d1758f8 Always pass test class to ActiveProfilesResolver
Prior to this commit, if @ActiveProfiles were used as a meta-annotation
on a composed annotation, then the composed annotation's class would be
passed to the ActiveProfilesResolver.resolve() method instead of the
test class, which breaks the contract for ActiveProfilesResolver.

This commit addresses this issue by ensuring that the actual test class
is always passed to ActiveProfilesResolver.resolve().

Issue: SPR-11467
2014-02-22 17:15:11 +01:00
Sam Brannen 34e90ba7f7 Simplify ContextLoaderUtilsActiveProfilesTests 2014-02-22 16:55:13 +01:00
Sam Brannen 7e38f479e0 Polishing 2014-02-21 22:56:23 +01:00
Sam Brannen 42a36349e9 Support nested meta-annotations in AnnotationUtils
Prior to this commit, AnnotationUtils.findAnnotation(Class, Class)
claimed to recursively search through annotations; however, only one
level of annotations was supported by the algorithm.

This commit alters the search algorithm so that nested meta-annotations
(i.e., meta-annotations on meta-annotations) are also supported.

Issue: SPR-11448
2014-02-19 18:27:44 +01:00
Sam Brannen 8f0849f328 Fix minor error in AnnotationUtilsTests
TransactionalAndOrderedClass now extends TransactionalClass.

The tests passed anyway, but they did not actually verify what was meant
to be verified.
2014-02-19 12:47:55 +01:00
Phillip Webb 461816735f Fix unused import warning 2014-02-18 19:37:06 -08:00
Spring Buildmaster 8018ee7ce6 Next development version 2014-02-18 16:53:21 -08:00
Rossen Stoyanchev edba32b309 Add processExternalEntities support to OXM
Update OXM AbstractMarshaller to support processing of external
XML entities. By default external entities will not be processed.

Issue: SPR-11376
2014-02-18 15:54:30 -08:00
Phillip Webb 7efd54e243 Additional caching for ResolvableTypes
Add additional caching to ResolvableTypes and SerializableTypeWrapper
in order to improve SpEL performance.

Issue: SPR-11388
2014-02-18 15:27:28 -08:00
Phillip Webb 319724f0b4 Regularly purge ResolvableType cache
Update ResolvableType to call `purgeUnreferencedEntries` on the cache
on each get.

Issue: SPR-11394
2014-02-18 15:16:03 -08:00
Phillip Webb 2b4c81e642 Fix memory leak in ConcurrentReferenceHashMap
Update ConcurrentReferenceHashMap to protect against references that
have been garbage collected but for some reason do not appear as a
`pollForPurge` result.

Also added purgeUnreferencedEntries() method to allow for programmatic
cleanup.

Issue: SPR-11440
2014-02-18 15:10:30 -08:00
Sam Brannen fe6a9826c5 Fix typo in AbstractDelegatingSmartContextLoader 2014-02-18 18:42:44 +01:00
Rossen Stoyanchev 268657b6cb Add PropertyNamingStrategy field to ObjectMapperFB
Issue: SPR-11431
2014-02-17 14:57:22 -05:00
Brian Clozel 1dedb67fbc Set virtualHost on StompBrokerRelayRegistration
Prior to this commit, one couldn't set the virtualHost property on
StompBrokerRelayMessageHandler via JavaConfig, since
StompBrokerRelayRegistration's API didn't offer that possibility.

This commit adds a new method in StompBrokerRelayRegistration's fluent
API to set the virtualHost used by StompBrokerRelayMessageHandler.
Note: this property is already configurable via xml config.

Issue: SPR-11433
2014-02-17 14:51:05 +01:00
Juergen Hoeller bde4964af5 Polishing 2014-02-14 23:48:13 +01:00
Juergen Hoeller 8a96d1a6ee Polishing 2014-02-14 23:40:03 +01:00
Juergen Hoeller ef1748f694 EhCache/JCacheCacheManager needs to re-obtain runtime-added Cache reference for potential decoration
Issue: SPR-11407
2014-02-14 21:58:48 +01:00
Juergen Hoeller 14e5a02870 Mixed polishing along with recent changes 2014-02-14 21:39:40 +01:00
Juergen Hoeller 9c6df766cd Related polishing
Issue. SPR-11428
2014-02-14 21:38:44 +01:00
Juergen Hoeller f913940402 Avoid unnecessary getMappingForMethod repeat (in particular for RequestMappingInfo)
Issue. SPR-11428
2014-02-14 20:48:40 +01:00
Juergen Hoeller 72fe7ebc34 Objects with multi-threaded access should not lazily populate a hash field
Issue. SPR-11428
2014-02-14 20:46:34 +01:00
Brian Clozel 6fba8292f5 Restrict ETag generation in ShallowEtagHeaderFilter
Prior to this commit, all 2xx HTTP responses were eligible for ETag
generation in ShallowEtagHeaderFilter. In some cases, this would use
CPU resources for no reason since HTTP clients would not use ETags.

This commit is an optimization and restricts ETags generation in cases
where (all conditions must be met):
- response has a 2xx status
- request is a GET
- response does not contain "no-store" in its "Cache-Control" header

Issue: SPR-11110
2014-02-14 09:52:40 +01:00
Juergen Hoeller d550ffb37f Clarified CompositeCacheManager's applicability, added convenience constructor with given delegates, and fixed getCacheNames implementation to never return duplicates
Issue: SPR-11427
2014-02-14 01:41:53 +01:00
Juergen Hoeller 34d397efa9 Restored original detectHandlerMethods call chain for backwards compatibility with custom subclasses (such as in Spring Integration) 2014-02-14 01:30:16 +01:00
Rossen Stoyanchev 32e5f57e64 Ensure matching user destination returned
Before this change, when a client subscribed to a "user" destination
(e.g. /user/foo), actual messages received in response to that
subscription contained the server-translated, unique user destination
(e.g. /foo-user123).

This is not an issue for clients such as stomp.js since the
subscription is unique and sufficient to match subscription responses.
However, other STOMP clients do additional checks on the destination
of the subscription and the response.

This change ensures that messages sent to clients on user destionations
always contain a destination that matches the one on the original
subscription.

Issue: SPR-11423
2014-02-13 16:38:56 -05:00
Rossen Stoyanchev 741b4b229a Add encoding for the default action in FormTag
Issue: SPR-11426
2014-02-13 14:36:12 -05:00
Rossen Stoyanchev 0cb27f4bc5 Allow HttpMethod as a controller method argument
Issue: SPR-11425
2014-02-13 12:16:24 -05:00
Rossen Stoyanchev b1abe26b33 Add ResultMatchers for status code ranges
Issue: SPR-11424
2014-02-13 11:45:12 -05:00
Sam Brannen 206655c2b4 Polishing 2014-02-13 02:25:21 +01:00
Sam Brannen 1ae3eba89a Merge from sbrannen/SPR-10785
* SPR-10785:
  Fix CGLIB memory leak for method injection
2014-02-13 02:09:26 +01:00
Sam Brannen 8028eae786 Fix CGLIB memory leak for method injection
This commit continues the work for fixing memory leaks resulting from
CGLIB subclass generation for beans relying on method injection.

- Set proxy callbacks on the CGLIB Factory (i.e., the instance) instead
  of in the generated subclass (i.e., via the Enhancer).

- Convert private inner classes in CglibSubclassingInstantiationStrategy
  to private static classes in order to avoid unnecessary coupling to
  classes generated using CGLIB.

- Tidy up XmlBeanFactoryTests.

- Update logic in serializableMethodReplacerAndSuperclass() so that it
  finally aligns with the decision made for SPR-356.

Issue: SPR-10785, SPR-356
2014-02-13 01:45:41 +01:00
Juergen Hoeller bda8f2b4cf Upgraded to Jetty 9.1.2 and Guava 16.0.1 2014-02-13 01:09:16 +01:00
Juergen Hoeller ce39146be8 Polishing 2014-02-13 01:08:35 +01:00
Sam Brannen f2a4537b6c Test against CGLIB memory leak for method injection
This commit introduces a test in XmlBeanFactoryTests that verifies that
CGLIB generated subclasses for method injected beans are reused across
bean factories for identical bean definitions. In other words, by
verifying that the same CGLIB generated class is reused for identical
bean definitions, we can be certain that Spring is no longer generating
identical, duplicate classes that consume memory in the VM.

Issue: SPR-10785, SPR-11420
2014-02-13 00:28:37 +01:00
Juergen Hoeller 674169fe07 Actually upgraded to Gradle 1.11 2014-02-13 00:10:21 +01:00
Juergen Hoeller 520ef9ec23 Polishing
Issue: SPR-11422
2014-02-12 23:48:37 +01:00
Juergen Hoeller 603cdea26e resolveFactoryMethodIfPossible considers nonPublicAccessAllowed and SecurityManager
Issue: SPR-11422
2014-02-12 23:48:16 +01:00
Juergen Hoeller 0ec99fdef7 Polishing 2014-02-12 18:36:04 +01:00
Juergen Hoeller 6f58491b9c MarshallingView explicitly skips BindingResult when searching for a model object
Just implementing common custom subclass behavior out-of-the-box...

Issue: SPR-11417
2014-02-12 18:35:36 +01:00
Juergen Hoeller 3716a8ef7d Upgraded to Gradle 1.11 2014-02-12 18:29:14 +01:00
Rossen Stoyanchev 891ec56607 Upgrade to Tomcat 8.0.3 2014-02-12 11:06:51 -05:00
Rossen Stoyanchev dfe2234781 Upgrade to Undertow 1.0 Final (WildFly 8 Final) 2014-02-12 11:06:51 -05:00
Sam Brannen 9534245660 Exclude overloaded from equals & hashCode in MethodOverride
Prior to this commit, the inclusion of the 'overloaded' flag in the
implementations of equals() and hashCode() in MethodOverride could lead
to adverse effects in the outcome of equals() in AbstractBeanDefinition.

For example, given two bean definitions A and B that represent the
exact same bean definition metadata for a bean that relies on method
injection, if A has been validated and B has not, then A.equals(B) will
potentially return false, which is not acceptable behavior.

This commit addresses this issue by removing the 'overloaded' flag from
the implementations of equals() and hashCode() for MethodOverride.

Issue: SPR-11420
2014-02-12 16:56:03 +01:00
Juergen Hoeller 8ae3aa7f59 Upgraded to Commons Logging 1.1.3 2014-02-12 00:13:16 +01:00
Juergen Hoeller cead06a3d9 Polishing 2014-02-12 00:12:52 +01:00
Juergen Hoeller 4a45af0038 AbstractHandlerMethodMapping should reuse BeanFactory.getType result 2014-02-12 00:11:36 +01:00
Juergen Hoeller 949338009b Ignore container callback and marker interfaces for auto-proxy decisions
Issue: SPR-11416
2014-02-12 00:01:20 +01:00
Juergen Hoeller 1a1c72ce4b Revised InvocableHandlerMethod exception handling
Issue: SPR-11281
2014-02-11 23:48:10 +01:00
Juergen Hoeller 5f1592a61a Consistently avoid close() call on Servlet OutputStream
Issue: SPR-11413
2014-02-11 23:42:37 +01:00
Juergen Hoeller 648245b200 MarshallingView should not close response OutputStream after copying to it
Also throws IllegalStateException instead of ServletException now, consistent with other Spring MVC classes.

Issue: SPR-11411
2014-02-11 23:41:09 +01:00
Rossen Stoyanchev 7301b58ec9 Improve info on use of @Controller's with aop proxying
Before this change, issues surrounding the use of @Controller's in
combination with AOP proxying, resulted in an IllegalArgumentException
when trying to invoke the controller method.

This change detects such cases proactively and reports them with a
clear recommendation to use class-based proxying when it comes to
@Controller's. This is the most optimcal approach for controllers
in many respects, also allows @MVC annotations to remain on the
class.

The documentation has also been updated to have a specific section
on @Controller's and AOP proxying providing the same advice.

Issue:SPR-11281
2014-02-11 12:25:54 -05:00
Rossen Stoyanchev 12598f8581 Fix issue w/ use of UrlPathHelper's urlDecode property
Before this change the getPathWithinServletMapping method of
UrlPathHelper could not work properly when a default servlet mapping
(i.e. "/") was used in combination with urlDecode=false. The fact that
the getServletPath() method of HttpServletRequest always returns a
decoded path was getting in the way.

Although there is no way to check Servlet mappings through the Servlet
API, this change aims to detect the given scenario and returns the full
path following the context path thus avoiding URL decoding.

Note that the same can be achieved by setting urlDecode=false and
alwaysUseFullPath=true. However this change ensures that urlDecode
works properly without having to know that.

Issue: SPR-11101
2014-02-10 21:08:57 -05:00
Rob Winch 14616a445a Update javadoc to conform to JDK8 styling
Issue: SPR-11412
2014-02-10 15:07:34 -06:00
Sam Brannen b4f1a4c6dc Merge pull request #458 from abobov/master
Fix example in Javadoc for ResultActions.andExpect()
2014-02-10 15:23:48 +01:00
Anton Bobov 1cf38a98a4 Fixed example in JavaDoc.
mimeType is not a valid method on ContentResultMatche.

I have signed and agree to the terms of the SpringSource Individual
Contributor License Agreement.
2014-02-10 14:23:10 +06:00
Sam Brannen ac22b786be Delete unused imports 2014-02-09 18:58:41 +01:00
Juergen Hoeller 57c4eca039 Revised ExcelViewTests 2014-02-09 01:34:34 +01:00
Juergen Hoeller 53aab24690 Polishing 2014-02-09 01:08:56 +01:00
Juergen Hoeller 74ad2081aa Upgraded to JasperReports 5.5.1 2014-02-09 01:08:45 +01:00
Sam Brannen f77bf2422e Polish Javadoc for LookupOverride and related code 2014-02-09 00:30:44 +01:00
Sam Brannen c335e99e3f Remove trailing whitespace from source code 2014-02-08 17:30:39 +01:00
Sam Brannen 1f778530b5 Polish test classes
- Consistent importing of org.junit.Assert.*;
- Proper declaration of expected exceptions via @Test(expected).
- Renamed SpEL ExpressionTestCase to AbstractExpressionTests.
- Formatting and test method naming conventions.
2014-02-08 17:24:11 +01:00
Sam Brannen f717b55035 Fix test bug related to legacy JUnit AssertionFailedError
AssertionFailedError was thrown by JUnit 3.8. Since RedirectViewTests
has been upgraded to JUnit 4, now standard java.lang.AssertionErrors are
thrown. Thus, attempting to catch an AssertionFailedError is futile.

Of course, since these tests have not been failing, it is likely a moot
point, but changing the try-catch blocks to catch a possible
AssertionError can't be a bad thing.
2014-02-08 16:14:26 +01:00
Sam Brannen 08842f3fdf Delete legacy JUnit 3.8 test from spring-test 2014-02-08 15:50:04 +01:00
Sam Brannen 2d5c5fc18e Delete legacy JUnit 3.8 test from spring-test 2014-02-08 15:49:07 +01:00
Juergen Hoeller 8c0e3040c2 Polishing 2014-02-07 18:06:13 +01:00
Juergen Hoeller 749b65b0b2 Polishing 2014-02-07 17:42:37 +01:00
Juergen Hoeller 99f9dce14a Fixed all List return types to ? instead of Object, restoring backwards compatibility with existing Spring 3.2.x based code and allowing easier casts to other element types
Also declaring findByExample generically based on the given example object's type.

Issue: SPR-11402
2014-02-07 17:39:55 +01:00
Juergen Hoeller 919d6ccb3b Actually log the cause of canRead/canWrite failures
Issue: SPR-11403
2014-02-07 17:27:17 +01:00
Juergen Hoeller 9a8f860318 Fixed broken link to jax-ws-commons website
Issue: SPR-11404
2014-02-07 17:24:47 +01:00
Juergen Hoeller 631b07aef8 Upgraded to Commons FileUpload 1.3.1 2014-02-07 17:23:31 +01:00
Sam Brannen de5b7a378b Fix grammar and update link in Javadoc for SimpleThreadScope 2014-02-07 12:27:35 +01:00
Sam Brannen f1d146f305 Merge pull request #457 from mebigfatguy/master
Fix typo in log output for SimpleThreadScope
2014-02-07 12:15:06 +01:00
Dave Brosius cdd2324ab5 fix log spelling typo 2014-02-06 19:58:20 -05:00
Rossen Stoyanchev 42d0470d94 Improve expanding in MvcUriComponentsBuilder
Before this change MvcUriComponentsBuilder could not create a
UriComponentsBuilder for methods where the mapping has a URI variable
and no matching method argument for it.

For example a URI variable may be in the type-level mapping but not
all methods may have an @PathVariable argument for it.

This fix addresses the shortcoming such that MvcUriComponentsBuilder
expands the method argument values available to it and leaves remaining
URI variables to be further expanded via UriComponents.expand().

Issue: SPR-11391
2014-02-06 16:55:19 -05:00
Rossen Stoyanchev bdb742b8db Polish MvcUriComponentsBuilder
Issue: SPR-11391
2014-02-06 16:55:19 -05:00
Juergen Hoeller 09e2e5897d Removed outdated hibernate3 references across the codebase
Issue: SPR-9028
2014-02-06 22:15:59 +01:00
Juergen Hoeller 2410e29dda Introduced OpenSessionInterceptor as a streamlined alternative to HibernateInterceptor
Issue: SPR-9028
2014-02-06 22:13:52 +01:00
Sam Brannen 7566ceb5f2 Fix minor typo in testing chapter 2014-02-06 21:47:42 +01:00
Sam Brannen 9a6252d715 Fix formatting in 'TCF support classes' section of ref
This commit fixes some formatting issues in the 'TestContext Framework
support classes' section of the reference manual that were introduced
in the conversion from DocBook to AsciiDoc.
2014-02-06 21:12:00 +01:00
Juergen Hoeller 426f52b393 Polishing 2014-02-06 20:35:59 +01:00
Juergen Hoeller 8c4e372558 Introduced SpringNamingPolicy for CGLIB
Issue: SPR-11398
2014-02-06 20:25:11 +01:00
Sam Brannen 522d136bbd Delete TODO that is now tracked in JIRA
Issue: SPR-11393
2014-02-06 14:12:03 +01:00
Rossen Stoyanchev f636ccb5eb Fix failing test 2014-02-05 22:02:59 -05:00
Rossen Stoyanchev 46c0e45130 Improve header processing in SimpMessagingTemplate
Headers provided to the SimpMessagingTemplate's convertAndSend methods
are now automatically moved into the "nativeHeaders" sub-map. This
ensures the headers will go out with the STOMP message and be received
by subscribers.

Issue: SPR-11387
2014-02-05 21:25:35 -05:00
Sam Brannen 624170f178 Introduce verify & reset methods in ADSEMockCtrl
This commit introduces static verify() and reset() methods in
AnnotationDrivenStaticEntityMockingControl for programmatic control
on the mock.

Issue: SPR-11395
2014-02-05 23:18:41 +01:00
Sam Brannen edb0b0e84b Merge pull request #455 from sdeleuze/SPR-11392
Fix EvalTagTests with locales other than english
2014-02-05 20:22:40 +01:00
Sam Brannen 81c259fe42 Explain mock scope in static method mocking aspect 2014-02-05 20:17:34 +01:00
Sam Brannen 67142dcb0a Polish Javadoc in @*ExceptionHandler 2014-02-05 20:15:50 +01:00
Sebastien Deleuze 261a863e8f Fix EvalTagTests with locales other than english
Fix testPrintFormattedScopedAttributeResult test in org.springframework.web.servlet.tags.EvalTagTests class by making an assertion which is not locale dependent.

Issue: SPR-11392
2014-02-05 18:01:57 +01:00
Sam Brannen 9fe9e27189 Explain after advice behavior in static method mock aspect
This commit makes it clear that mock verification will not occur if an
advised test method throws an exception.
2014-02-05 15:57:52 +01:00
Sam Brannen 76f3d6e501 Improve test coverage for AbstractMethodMockingControl
This commit improves the test coverage for AbstractMethodMockingControl
by introducing tests that verify expected behavior for:

 - reentrant method invocations via public methods
 - reentrant method invocations via private methods
 - test methods that do not set expectations or invoke playback()
 - test methods that throw exceptions

For a more complete discussion of "after" vs. "after returning" advice
within AbstractMethodMockingControl, see the Javadoc in the tests.
2014-02-05 15:41:47 +01:00
Sam Brannen 3a89bc4b26 Fix merge error in previous commit
Issue: SPR-11385
2014-02-04 23:27:55 +01:00
Sam Brannen 69a89b1bb0 Fix off-by-one regression in AbstractMethodMockingControl
This commit fixes the off-by-one regression accidentally introduced in
commit 55961544a7.

Specifically, this fix ensures that the correct recorded call is
indexed in the 'calls' list in the implementation of
AbstractMethodMockingControl.Expectations.nextCall().

In addition, this commit improves the Javadoc for
AbstractMethodMockingControl, @MockStaticEntityMethods, and
AnnotationDrivenStaticEntityMockingControl and introduces a proper
toString() implementation for the internal Expectations.Call class in
AbstractMethodMockingControl. Furthermore, code from the obsolete
Delegate test class has been inlined in
AnnotationDrivenStaticEntityMockingControlTests.

Issue: SPR-11385, SPR-10885
2014-02-04 23:14:39 +01:00
Juergen Hoeller 1cd5071e6a Use AtomicInteger instead of local synchronization around int field
Issue: SPR-11103
2014-02-04 17:45:03 +01:00
Juergen Hoeller 8a6b095204 Polishing
Issue: SPR-11386
2014-02-04 17:41:42 +01:00
Juergen Hoeller 6634c19e6a Related polishing
Issue: SPR-11386
2014-02-04 16:45:14 +01:00
Juergen Hoeller 60c1905cdd Introduced "spring.jdbc.getParameterType.ignore" property
Issue: SPR-11386
2014-02-04 16:44:08 +01:00
Rossen Stoyanchev 1a8629d408 Fix failing test 2014-02-03 21:44:13 -05:00
Sam Brannen d90a36170a Polish Javadoc for @MockStaticEntityMethods & its aspect 2014-02-03 23:47:02 +01:00
Sam Brannen b8ed2f4967 Ensure all tests are executed in the Gradle build
Prior to this commit several test classes named "*Test" were not
recognized as tests by the Gradle build. This is due to the configured
inclusion of '**/*Tests.*' which follows Spring's naming convention for
test classes.

This commit addresses this issue by:

 - Renaming real test classes consistently to "*Tests".
 - Renaming internal test classes to "*TestCase".
 - Renaming @WebTest to @WebTestStereotype.
 - Disabling broken tests in AnnoDrivenStaticEntityMockingControlTest.
 - Modifying the Gradle build configuration so that classes ending in
   either "*Tests" or "*Test" are considered test classes.

Issue: SPR-11384
2014-02-03 23:16:47 +01:00
Rossen Stoyanchev 1c5cab2a40 Add external entity test
Issue: SPR-11376
2014-02-03 16:57:03 -05:00
Juergen Hoeller f053f60630 Revised javadoc and related polishing
Issue: SPR-11383
2014-02-03 16:05:00 +01:00
Juergen Hoeller d55c22ec85 Upgraded to Apache HttpComponents HttpClient 4.3.2
Issue: SPR-11383
2014-02-03 16:02:05 +01:00
Juergen Hoeller f27304d785 Avoid repeated assignability check for raw class on fallback match, since AutowireCandidateResolver is only being called for basic type matches to begin with
Issue: SPR-9965
2014-02-01 19:28:40 +01:00
Juergen Hoeller 874a2a9ca2 Backwards-compatible handling of generic and raw collection converters
Issue: SPR-11369
2014-02-01 19:24:40 +01:00
Rossen Stoyanchev e6f4796779 Fix failing test 2014-02-01 10:46:51 -05:00
Juergen Hoeller 46b24dbd33 Polishing
Issue: SPR-11369
2014-02-01 12:15:01 +01:00
Juergen Hoeller 5f2429429f Defensively handle ServletRequestAttributes casting in requestDestroyed callback
Issue: SPR-11378
2014-02-01 11:04:36 +01:00
Juergen Hoeller d52f584322 GenericConversionService matches converters by full generic target type, allowing for the registration of multiple converters from the same source type to different collection types
Issue: SPR-11369
2014-02-01 10:53:01 +01:00
Rossen Stoyanchev da369aa826 Add null check after message conversion
AbstractMessageSendingTemplate now checks if MessageConverter.toMessage
returns null and raises an exception.

Issue: SPR-11370
2014-01-31 21:34:18 -05:00
Rossen Stoyanchev f0a53ae54e Fine-tune default mime type in message broker config
Issue: SPR-11370
2014-01-31 20:55:07 -05:00
Rossen Stoyanchev b6da7e2795 Fix test in Jaxb2RootElementHttpMessageConverterTests 2014-01-31 20:17:44 -05:00
Sam Brannen a521ef5cee Verify ServletCtxAware beans are processed in WAC tests
SPR-11145 claims that ServletContextAware beans declared in an
ApplicationContext loaded for an integration test by the TestContext
framework (TCF) do not have their setServletContext() methods invoked
if the tests are executed manually using JUnit 4.11.

This commit verifies that such ServletContextAware beans are processed
properly regardless of how the test was launched. Specifically:

 - A ServletContextAwareBean has been introduced.

 - BasicAnnotationConfigWacTests has been retrofitted with a
   ServletContextAwareBean in its context.

 - ServletContextAwareBeanWacTests has been introduced to execute
   BasicAnnotationConfigWacTests manually via JUnitCore.

Issue: SPR-11145
2014-02-01 02:08:21 +01:00
Juergen Hoeller 4f60b98bca Consistent iteration over actualValue in Velocity and FreeMarker macros
This requires consistent exposure of an actualValue in BindStatus, even if no BindingResult available.

Issue: SPR-10837
2014-01-31 22:39:20 +01:00
Rossen Stoyanchev e680e34620 Fix test class name 2014-01-31 16:26:28 -05:00
Sam Brannen 474f1b03cd Fix grammar in Javadoc for @ResponseBody 2014-01-31 17:02:40 +01:00
Sam Brannen 8c3868a8dd Polish Javadoc for EmbeddedDatabaseFactory 2014-01-31 13:33:55 +01:00
Juergen Hoeller c2303854d1 Polishing
Issue: SPR-11372
2014-01-31 13:17:55 +01:00
Juergen Hoeller 5be8301128 Fixed isMatchingFieldError to properly handle empty field name
Also avoided unnecessary substring creation for field error access with wildcard.

Issue: SPR-11374
2014-01-31 12:47:08 +01:00
Juergen Hoeller a537eb3a6a Polishing 2014-01-30 12:26:41 +01:00
Juergen Hoeller c1eac209c3 Fixed LiveBeansView to not produce invalid JSON if last bean is not eligible
Also introducing overridable isBeanEligible template method.

Issue: SPR-11366
2014-01-30 12:26:22 +01:00
Spring Buildmaster 1af61ef1d5 Next development version 2014-01-28 12:16:35 -08:00
Juergen Hoeller 47395f6b0a Dropped explicit paragraph on web.xml version declaration
Issue: SPR-11364
(cherry picked from commit 36ab65a)
2014-01-28 17:34:27 +01:00
Juergen Hoeller 8570f607a7 Fixed regression with fallback for non-resolvable property type 2014-01-28 17:16:50 +01:00
Juergen Hoeller 786e217991 Minor polishing after previous polish step ;-) 2014-01-28 17:16:01 +01:00
Sam Brannen 63e023173b Polish Hibernate support and tests
- Fix Javadoc in HibernateTemplate so that it compiles in Eclipse.
 - Suppress generics warnings in HibernateTemplateTests.
 - Remove unnecessary deprecation warning suppression in constructor for
   LocalSessionFactoryBuilder.
2014-01-28 15:41:42 +01:00
Sam Brannen 5f8275a305 Merge pull request #453 from kryger/master
Fix typos and grammar in Cache Abstraction reference doc
2014-01-28 06:19:12 -08:00
Juergen Hoeller 1e303ac1af Polishing 2014-01-28 14:44:44 +01:00
Lukasz Kryger 14d3525a28 Minor corrections/typos to "27. Cache Abstraction" docs section 2014-01-28 12:30:04 +00:00
Juergen Hoeller c5f908b174 Consistent use of headersExtractor() template method 2014-01-28 12:56:53 +01:00
Juergen Hoeller c719c70ea9 Fixed 'globalJobListeners'/'globalTriggerListeners' to work with Quartz 2.0 & 2.1 as well
Issue: SPR-11362
2014-01-28 12:25:24 +01:00
Brian Clozel 425e5a066e Add RestTemplate constructor with custom converters
Prior to this commit, RestTemplate's constructors were all initializing
default HTTPMessageConverters. Its API provides a way to replace
those converters with custom ones, but default converters are already
defined and initialized at that point, which can be an issue in some
cases (performance, classpath...).

This commits adds a new constructor for RestTemplate with a list
of message converters as argument. With this new constructor,
default message converters are never initialized.

Issue: SPR-11351
2014-01-28 11:33:45 +01:00
Juergen Hoeller fcbd3b121b Added test for inconsistency between read and write method
Issue: SPR-11361
2014-01-28 01:25:59 +01:00
Juergen Hoeller d004b634a5 Fixed type resolution in case of inconsistencies between read and write method
Issue: SPR-11361
2014-01-28 00:46:15 +01:00
Juergen Hoeller 500d0da67d Polishing 2014-01-27 22:41:35 +01:00
Juergen Hoeller 1b0ce200e0 Consistent use of ${hibernate4Version} in build.gradle 2014-01-27 21:41:31 +01:00
Juergen Hoeller bf9702294d Polishing
Issue: SPR-11291
2014-01-27 21:38:20 +01:00
Juergen Hoeller 79e17dbfa0 Introduced HibernateTemplate for Hibernate 4 as a migration helper
Note that this variant of HibernateTemplate is stripped down in terms of Session management options and just provides a current-session style with a fallback to a temporary session-per-operation.  Furthermore, in the latter fallback mode, only read operations are supported, just like with a JPA EntityManager.

Issue: SPR-11291
2014-01-27 21:37:52 +01:00
Brian Clozel cc0a845653 Support Part/MultiPartFile arrays in ArgumentResolvers
Prior to this commit, parts of a multipart HTTP request could be
injected in @RequestPart and @RequestParam annotated arguments, when
using types:
* MultipartFile, Collection<MultiPartFile>
* javax.servlet.Part, Collection<Part>

This commits updates @RequestParam and @RequestPart argument resolvers
and now allows the array versions of those types:
* Part[]
* MultiPartFile[]

Note that the MockHtpServletRequest backing tests for standard
Servlets implementations now uses a MultiValueMap to store parts
(versus a simple hashmap).

Issue: SPR-11353
2014-01-27 18:09:29 +01:00
Sam Brannen 78542777d6 Introduce value attribute in @RestController
Stereotype annotations should support a 'value' attribute for
specifying the name of the Spring-managed component; however,
@RestController currently does not provide such an attribute.

This commit introduces a 'value' attribute in @RestController so that
developers can provide custom names for components annotated with
@RestController.

Issue: SPR-11360
2014-01-27 12:07:23 +01:00
Juergen Hoeller bb28d198f5 Polishing 2014-01-26 01:04:21 +01:00
Juergen Hoeller e0fd54b8c2 Upgraded SLF4J, JOpt, JRuby, Commons Pool & Commons DBCP to latest versions 2014-01-26 00:12:21 +01:00
Juergen Hoeller 56b7d7a94a Consistently declare @SuppressWarnings("serial") instead of dummy serialVersionUID 2014-01-26 00:11:11 +01:00
Juergen Hoeller 67e76e9a8d Compatibility with JOpt 4.6
JOpt 4.6 redeclared its nonOptionArguments() method from List<String> to List<?>, requiring us to select String arguments only as we do for regular option values already.

Issue: SPR-11359
2014-01-26 00:05:51 +01:00
Juergen Hoeller 98e890aae3 Consistently switched optional dependencies to scope 'optional' 2014-01-25 17:20:54 +01:00
Juergen Hoeller 4b282a965c Further reordering of dependencies 2014-01-25 17:13:34 +01:00
Juergen Hoeller 9154871a45 Raised all dependencies to latest possible maintenance releases; introduced additional library version variables; consistently grouped dependency scopes 2014-01-25 16:24:10 +01:00
Juergen Hoeller 61b6d398a5 Removed LocalDateToDateMidnightConverter pre-release since DateMidnight is deprecated as of Joda-Time 2.3; marked DateTimeToDateMidnightConverter as deprecated 2014-01-25 15:26:47 +01:00
Juergen Hoeller c1ef552359 Polishing 2014-01-25 15:26:27 +01:00
Sam Brannen eab69dbeec Upgrade XStream to 1.4.6 2014-01-25 15:14:07 +01:00
Sam Brannen 31a74b0ff6 Clean up generics warnings in spring-oxm tests 2014-01-25 14:17:25 +01:00
Sam Brannen 5e7811a45d Polish Javadoc in XStreamMarshaller 2014-01-25 14:03:18 +01:00
Sam Brannen d404473bc5 Introduce xstreamVersion constant in Gradle build 2014-01-25 13:33:27 +01:00
Juergen Hoeller 5331da6aff Polishing 2014-01-25 00:27:27 +01:00
Juergen Hoeller 21eb8db5bc Polishing
Issue: SPR-11357
2014-01-24 18:30:31 +01:00
Juergen Hoeller defc1d3157 Drop Introspector.flushFromCaches calls completely
According to the JDK's documentation and changelog, the Introspector itself safely handles weak references as of JDK 6 update 21 (which is what we require for Spring 4.0).

Issue: SPR-11356
2014-01-24 18:22:11 +01:00
Juergen Hoeller 167329ce0c Added test for SpringProperties setFlag method
Issue: SPR-9014
Issue: SPR-11297
(cherry picked from commit 23249cd)
2014-01-24 18:18:41 +01:00
Phillip Webb 2dcbf4d618 Merge pull request #445 from snicoll/commons-logging-doc
* commons-logging-doc:
  Improve 'switch off commons-logging' documentation
2014-01-24 08:53:14 -08:00
Stephane Nicoll 624f81a5a3 Improve 'switch off commons-logging' documentation
Update reference documentation to make it clearer that only
`spring-core` has a direct dependency on `commons-logging`.

Also reference the 'empty jar' alternative option as described in
the SLF4J FAQ.
2014-01-24 08:52:16 -08:00
Rossen Stoyanchev ab5f1256bf Allow consolidating config in root context with Java
This change makes it possible to provide no configuration for the
DispatcherServlet when extending
AbstractAnnotationConfigDispatcherServletInitializer, and therefore
provide all config through the "root" context.

Issue: SPR-11357
2014-01-24 11:09:12 -05:00
Juergen Hoeller b6073d9ac4 Polishing 2014-01-24 16:22:29 +01:00
Juergen Hoeller 8543b91c50 Introduced SpringProperties class and optional "spring.properties" file
This in particular allows for specifying "spring.getenv.ignore" and "spring.beaninfo.ignore" in a local way within the application, in case that JVM-level system properties are locked.

Issue: SPR-9014
Issue: SPR-11297
2014-01-24 16:22:02 +01:00
Sam Brannen 6151e6d12a Merge pull request #451 from hupfis/patch-1
Fix code example in Javadoc for ResultActions
2014-01-24 04:37:57 -08:00
Juergen Hoeller eeae5fba95 Fixed regression with constructing TypeDescriptor from null Class
Issue: SPR-11354
2014-01-24 13:16:35 +01:00
hupfis 0013a43237 Fixed code example in JavaDoc
equalTo is not a valid method on JsonPathResultMatchers

I have signed and agree to the terms of the SpringSource Individual Contributor License Agreement.
2014-01-24 09:26:09 +01:00
Juergen Hoeller 42db41e007 Polishing 2014-01-23 20:59:53 +01:00
Juergen Hoeller 86fc2dd556 Fixed regression in SpEL's constructor resolution
Issue: SPR-11348
2014-01-23 20:52:21 +01:00
Sam Brannen 8faf01f56d Fix "coercion" spelling mistakes in Javadoc 2014-01-23 17:47:35 +01:00
Juergen Hoeller 9c3a972dac Polishing
Issue: SPR-11297
(cherry picked from commit fc36184)
2014-01-23 00:16:29 +01:00
Juergen Hoeller 6793765b0a Factored out "suppressGetenvAccess()" method
Issue: SPR-11297
(cherry picked from commit 52d050d)
2014-01-23 00:12:09 +01:00
Juergen Hoeller 8d304efad1 Preserve visitBeanDefinition stacktrace in BeanDefinitionStoreException
Issue: SPR-11346
(cherry picked from commit fdd31c0)
2014-01-23 00:10:07 +01:00
Juergen Hoeller 3310ab55e0 Polishing
Issue: SPR-11344
(cherry picked from commit d434ef9)
2014-01-23 00:10:02 +01:00
Juergen Hoeller 6a6a23f0a3 Avoid class loading during AspectJ expression evaluation
Fixed through downcasting to AspectJ's ReflectionType and ReflectionBasedReferenceTypeDelegate, obtaining the myClass field there. We only fall back to regular class loading if we encounter any other kind of type.

Issue: SPR-11344
(cherry picked from commit c406c56)
2014-01-23 00:06:43 +01:00
Sam Brannen fb12e234fc Handle NoClassDefFoundError consistently for TELs
Prior to this commit, a NoClassDefFoundError caught in
TestContextManager's retrieveTestExecutionListeners() method would be
handled differently for implicit default listeners (i.e., listeners not
declared via @TestExecutionListeners) and listeners explicitly declared
via @TestExecutionListeners. Specifically, a NoClassDefFoundError would
cause a test to fail for an explicitly declared TestExecutionListener
but not for an implicitly declared one.

This commit addresses this issue by:

 - Always swallowing a NoClassDefFoundError for both implicitly and
   explicitly declared TestExecutionListeners.
 - Changing the log level from DEBUG to INFO to make such situations
   more visible to the average end user.

Issue: SPR-11347
2014-01-22 23:28:36 +01:00
Rossen Stoyanchev 09251dfad1 Fix typo 2014-01-22 16:49:00 -05:00
Rossen Stoyanchev a106e06a89 Expose failing test in GenericMessagingTemplateTests
Assertions made in callbacks invoked on separate thread were not
reaching the test framework. This fix ensures failures are detected
and cause tests to fail.
2014-01-22 16:43:21 -05:00
Rossen Stoyanchev 3ffc3d442d Document use of Jetty's WebSocketServerFactory
Issue: SPR-11023
2014-01-22 16:23:22 -05:00
Sam Brannen 3cb5828e21 Suppress warnings in MappingJacksonMsgConvTests 2014-01-22 21:09:06 +01:00
Sam Brannen 227320dc81 Suppress warnings in HibernateTransactionManagerTests 2014-01-22 20:53:55 +01:00
Rossen Stoyanchev 1c4530f251 Re-enable Undertow tests in WebSocketConfigurationIT 2014-01-22 14:50:25 -05:00
Gary Russell 0e7b94f9e9 Add constructors to MessageHandlingException
Issue: SPR-11345
2014-01-22 14:43:35 -05:00
Rossen Stoyanchev 74fe1aea31 Fix typo in documentation 2014-01-22 13:31:36 -05:00
Rossen Stoyanchev 8ee2a2d18c Remove unused constructor arg from UserDestinationMH 2014-01-22 11:55:44 -05:00
Sam Brannen 499c858cd4 Suppress resource/deprecation warnings in integration tests 2014-01-22 17:45:45 +01:00
Sam Brannen 8105011368 Delete unnecessary redeclaration of test methods
This commit deletes methods in RollbackForRequiredEjbTxDaoTestNGTests
that were unnecessarily redeclared. The redeclaration is required for
JUnit's @FixMethodOrder support but not for TestNG's built-in support
for dependent methods.

Issue: SPR-6132
2014-01-22 17:44:13 +01:00
Rossen Stoyanchev 0db2f79bdb Polish message method handling tests 2014-01-22 11:29:38 -05:00
Brian Clozel db9b6fa28e Split tests for MethodMessageHandlers impl.
Prior to this commit, all MethodMessageHandlers tests were
implemented in a single class. Since SimpAnnotationMsgHandler
has been refactored with an abstract class, tests also
needed such a refactoring.

This commit creates test fixtures for AbstractMethodMessageHandler.

Issue: SPR-11191
2014-01-22 10:42:24 -05:00
Rossen Stoyanchev 175aa86d79 Merge pull request #447 from snicoll/SPR-11331 2014-01-22 10:30:09 -05:00
Stephane Nicoll 98174e101f Improve documentation of matrix variables.
Prior to this commit, it was not clear how to enable the support of matrix
variables in the mvc namespace. As the feature is disabled by default, added
something to highlight the part that explains how to configure it

Issue: SPR-11331
2014-01-22 10:28:07 -05:00
Juergen Hoeller a599b57a74 Revised RootBeanDefinition's externallyManaged* Sets to rely on postProcessingLock
This allows us to avoid early initialization of footprint-heavy ConcurrentHashMaps, and reuses the existing postProcessingLock which will typically be active already when registerExternallyManaged* calls come in from the bean factory's post-processing phase.

Issue: SPR-11343
2014-01-22 14:20:33 +01:00
Sam Brannen e20c927c5e Merge pull request #449 from sbrannen/SPR-6132
Introduce EJB-based transactional tests in the TCF
2014-01-22 04:02:37 -08:00
Sam Brannen c0eafa9ea1 Introduce EJB-based transactional tests in the TCF
This commit introduces transactional integration tests executing
against both JUnit and TestNG in the TestContext framework (TCF) using
@TransactionAttribute in EJBs instead of Spring’s @Transactional
annotation.

These tests disprove the claims raised in SPR-6132 by demonstrating that
transaction support in the TCF works as expected when a transactional
EJB method that is configured with TransactionAttribute.REQUIRES_NEW is
invoked. Specifically:

 - The transaction managed by the TCF is suspended while such an EJB
   method is invoked.
 - Any work performed within the new transaction for the EJB method is
   committed after the method invocation completes.
 - The transaction managed by the TCF is resumed and subsequently
   either rolled back or committed as necessary based on the
   configuration of @Rollback and @TransactionConfiguration.

The configuration for the JUnit-based tests is straightforward and self
explanatory; however, the configuration for the TestNG tests is less
intuitive.

In order for the TCF to function properly, the developer must ensure
that test methods within a given TestNG test (whether defined locally,
in a superclass, or somewhere else in the suite) are executed in the
proper order. In a stand-alone test class this is straightforward;
however, in a test class hierarchy (or test suite) with dependent
methods, it is necessary to configure TestNG so that all methods within
an individual test are executed in isolation from test methods in other
tests. This can be achieved by configuring a test class to run in its
own uniquely identified suite (e.g., by annotating each concrete
TestNG-based test class with @Test(suiteName = "< Some Unique Suite
Name >")).

For example, without specifying a unique suite name for the TestNG
tests introduced in this commit, test methods will be executed in the
following (incorrect) order:

 - CommitForRequiredEjbTxDaoTestNGTests.test1InitialState()
 - CommitForRequiresNewEjbTxDaoTestNGTests.test1InitialState()
 - RollbackForRequiresNewEjbTxDaoTestNGTests.test1InitialState()
 - RollbackForRequiredEjbTxDaoTestNGTests.test1InitialState()
 - CommitForRequiredEjbTxDaoTestNGTests.test2IncrementCount1()

The reason for this ordering is that test2IncrementCount1() depends on
test1InitialState(); however, the intention of the developer is that
the tests for an individual test class are independent of those in
other test classes. So by specifying unique suite names for each test
class, the following (correct) ordering is achieved:

 - RollbackForRequiresNewEjbTxDaoTestNGTests.test1InitialState()
 - RollbackForRequiresNewEjbTxDaoTestNGTests.test2IncrementCount1()
 - RollbackForRequiresNewEjbTxDaoTestNGTests.test3IncrementCount2()
 - CommitForRequiredEjbTxDaoTestNGTests.test1InitialState()
 - CommitForRequiredEjbTxDaoTestNGTests.test2IncrementCount1()
 - CommitForRequiredEjbTxDaoTestNGTests.test3IncrementCount2()
 - RollbackForRequiredEjbTxDaoTestNGTests.test1InitialState()
 - RollbackForRequiredEjbTxDaoTestNGTests.test2IncrementCount1()
 - RollbackForRequiredEjbTxDaoTestNGTests.test3IncrementCount2()
 - CommitForRequiresNewEjbTxDaoTestNGTests.test1InitialState()
 - CommitForRequiresNewEjbTxDaoTestNGTests.test2IncrementCount1()
 - CommitForRequiresNewEjbTxDaoTestNGTests.test3IncrementCount2()

See the JIRA issue for more detailed log output.

Furthermore, @DirtiesContext(classMode = ClassMode.AFTER_CLASS) has
been used in both the JUnit and TestNG tests introduced in this commit
in order to ensure that the in-memory database is reinitialized between
each test class.

Issue: SPR-6132
2014-01-22 12:56:07 +01:00
Sam Brannen 597ef099d0 Suppress warnings and remove unused imports 2014-01-22 12:23:32 +01:00
Brian Clozel 845a6b0b7d Remove serialVersionUIDs in spring-messaging Exc.
Prior to this commit, several spring-messaging exceptions
had defined serialVersionUIDs. Those exception aren't
supposed to leave the system via Java serialization; also,
their deserialization is supported only against the same
version of Spring.

Issue: SPR-11339
2014-01-22 11:37:04 +01:00
Juergen Hoeller 12c393eb6d Switched 'order' attributes across namespaces to 'xsd:token'
Issue: SPR-10886
Issue: SPR-7342
2014-01-22 11:35:21 +01:00
Juergen Hoeller 3969467851 Temporarily deactivated Undertow integration tests
Undertow tests fail against OpenJDK 8 build 124 with a BindException.
2014-01-22 11:34:27 +01:00
Phillip Webb 59604b1cd5 Unwrap TypeVariables before calling .equals()
Update ResolvableType to unwrap Serialization wrapped TypeVariables
before calling the equals method.

This protects against the recent change in OpenJDK 8 (build 124)
which changed the TypeVariableImpl equals method such that it only
matches against other TypeVariableImpl instances.

Issue: SPR-11342
2014-01-21 16:10:02 -08:00
Rossen Stoyanchev d03fb8954b Encode user names in user destanations
Issue: SPR-11302
2014-01-21 14:57:51 -05:00
Phillip Webb d96b91a57b Fix SerializableTypeWrapper equals() performance
Change SerializableTypeWrapper proxies to directly call equals() methods
on the underlying Type, rather than possibly generating more wrappers.

This should help to improve performance, especially as the equals()
method is called many times when the ResolvableType cache is checked.

Issue: SPR-11335
2014-01-21 10:59:25 -08:00
Rossen Stoyanchev ae06c3a6ab Use DestinationUserNameProvider with @SendTo
Issue: SPR-11327
2014-01-21 12:32:35 -05:00
Rossen Stoyanchev e4ad2b352e Add DestinationUserNameProvider interface
The interface is to be implemented in addition to
java.security.Principal when Principal.getName() is not globally unique
enough for use in user destinations.

Issue: SPR-11327
2014-01-21 12:12:05 -05:00
Rossen Stoyanchev 2cafe9d73a Polish 2014-01-21 12:12:05 -05:00
Juergen Hoeller 3514242486 SourceHttpMessageConverter's supports implementation needs to check for StAXSource
Issue: SPR-11341
2014-01-21 16:35:47 +01:00
Juergen Hoeller 9cc86a3c80 Fixed setDeliveryPersistent javadoc
Issue: SPR-3983
2014-01-21 16:28:44 +01:00
Juergen Hoeller 4ae893e110 DefaultPersistenceUnitManager detects META-INF/orm.xml for scanned default unit
Note: A default orm.xml file is only being used when not co-located with a persistence.xml file, since we assume it is intended for use with that persistence.xml file only then.

Issue: SPR-11234
Issue: SPR-11260
2014-01-21 15:04:36 +01:00
Sam Brannen 3370f8b1b1 Include ServletTEL in abstract base test classes
The ServletTestExecutionListener is now prepended to the set of default
listeners in AbstractJUnit4SpringContextTests and
AbstractTestNGSpringContextTests.

Issue: SPR-11340
2014-01-21 15:01:29 +01:00
Sam Brannen 098d7c7465 Ensure all tests in spring-test are executed
Prior to this commit TestNG tests would only be executed by the Gradle
build if they were located in the “testng” package. Tests in subpackages
would therefore be omitted from the build.

This commit ensures that all TestNG classes in the “testng” package and
any of its subpackages are executed in the Gradle build.

Furthermore, this commit ensures that the JUnit-based
FailingBeforeAndAfterMethodsTests test class is executed along with the
other JUnit tests even though it resides under the “testng” package.

Issue: SPR-11338
2014-01-21 14:47:37 +01:00
Sam Brannen 4a569e6b1a Introduce hibernate3Version constant in Gradle build 2014-01-21 14:09:31 +01:00
Juergen Hoeller 84310c8a11 RemoteInvocation(Result) explicitly designed for JavaBean-style deserialization
Issue: SPR-11337
2014-01-21 12:49:16 +01:00
Brian Clozel eac4881809 Make RequestMappingHandlerMapping xml config easier
Prior to this commit, it was necessary to override
the HandlerMapping definition to change properties
like useSuffixPatternMatch, useSuffixPatternMatch...
Also, one couldn't set custom pathmatcher/pathhelper
on RequestMappingHandlerMapping via XML configuration.

This commits adds a new "mvc:annotation-driven"
subelement called "mvc:path-matching" for the tag
that allows to configure such properties:
* suffix-pattern
* trailing-slash
* registered-suffixes-only
* path-matcher
* path-helper

Note: this is a new take on this issue, since
96b418cc has been reverted by e2b99c3.

Issue: SPR-10163
2014-01-21 09:35:36 +01:00
Brian Clozel 8edb7a18cc Revert previous impl for SPR-10163
This reverts commit 96b418cc8a,
"Make RequestMappingHandlerMapping xml config easier".

This implementation makes the mvc:annotation namespace less readable,
and future configuration items would add even more to this namespace.

Issue: SPR-10163
2014-01-21 09:35:36 +01:00
Rossen Stoyanchev 17e492e641 Polish
Issue: SPR-11129
2014-01-20 21:48:57 -05:00
Stephane Nicoll 7df25764af Allow HttpHeaders return values for @MVC methods
Allow HttpHeader instances to be returned directly from MVC controller
methods managed by HandlerMethodReturnValueHandler rather than needing
to be wrapped in a ResponseEntity.

Issue: SPR-11129
2014-01-20 21:48:57 -05:00
Phillip Webb b92e4299b8 Upgrade to jexcelapi 2.6.12 and fix test failures
Upgrade to the latest release of jexcelapi and work-around the
ArrayIndexOutOfBounds test exception on *nix machines.

Issue: SPR-11334
2014-01-20 16:52:15 -08:00
Juergen Hoeller 709ac28f29 Consider wildcard type without bounds as eligible for fallback match too
Issue: SPR-11250
2014-01-21 01:26:30 +01:00
Juergen Hoeller 96d6963d61 Deprecated AbstractJExcelView since JExcelAPI is an abandoned project
JXL had no release since 2009, and has some serious bugs remaining: e.g. JXL on Unix cannot read template files created on Windows, using the 'latest' JXL 2.6.12 release.
2014-01-21 01:22:43 +01:00
Juergen Hoeller 1aff833282 Polishing 2014-01-21 00:35:38 +01:00
Juergen Hoeller 8281b93596 General ExcelViewTests code update
Issue: SPR-11334
2014-01-21 00:20:54 +01:00
Phillip Webb a9ff1403c3 Roll back jexcelapi from 2.6.12 to 2.6.3
JExcelAPI 2.6.12 appears to be causing ArrayIndexOutOfBoundsException
with the build. Rolling back to the earlier version for now
2014-01-20 14:00:05 -08:00
Phillip Webb 6bb6b6e6b5 Fix warnings in HeaderMethodArgumentResolver 2014-01-20 13:53:17 -08:00
Rossen Stoyanchev 5053fdc8c9 Resolve native header values with @Header
The @Header annotation in spring-messaging now resolves values from the
nested "nativeHeaders" map as well as top-level header map values.

In case of ambiguity (a value that exists in both), the top-level map
value is used and a warning message is printed. This is unlikly in most
cases but can be resolved by prefixing the header value with
"nativeHeadres.myHeader".

Issue: SPR-11326
2014-01-20 16:28:27 -05:00
Juergen Hoeller 5e5add4862 Locale/ThemeChangeInterceptor alignment and javadoc polishing
Issue: SPR-11128
2014-01-20 21:49:36 +01:00
Juergen Hoeller cc81aae8c1 Consistent evaluation of empty theme names to default theme name
Issue: SPR-11128
2014-01-20 21:49:28 +01:00
Juergen Hoeller 88730bdaa5 Added info-level logging for default unit detection
Issue: SPR-11333
2014-01-20 21:48:20 +01:00
Rossen Stoyanchev b4e48d6749 Fix issue in DefaultUserDestinationResolver
DefaultUserDestinationResolver now uses the session id of
SUBSCRIBE/UNSUBSCRIBE messages rather than looking up all session id's
associated with a user.

Issue: SPR-11325
2014-01-20 15:41:22 -05:00
Rossen Stoyanchev 809a5f59b3 Fix typo in reference
Issue: SPR-11311
2014-01-20 15:03:09 -05:00
Rossen Stoyanchev 19859fdb35 Add section on test STOMP/WebSocket applications
Issue: SPR-11266
2014-01-20 14:55:47 -05:00
Rossen Stoyanchev c376ee92cd Allow setting Cookie header
Issue: SPR-11332
2014-01-20 13:25:57 -05:00
Juergen Hoeller d1b1770eba Exposing AspectJ 1.7.4 to users, only using AspectJ 1.8.0.M1 for ajc in our build
Issue: SPR-11273
2014-01-20 17:41:12 +01:00
Juergen Hoeller f15a5fef8e Fixed assert in setAspectJAdvisorFactory()
Issue: SPR-11330
2014-01-20 17:37:50 +01:00
Brian Clozel f0449c6caa Update org and repo info in gradle build config
Issue: SPR-11213
2014-01-20 17:02:40 +01:00
Juergen Hoeller e1cb96c484 Updated optional dependencies to most recent minor versions 2014-01-20 15:30:34 +01:00
Phillip Webb 9076c70d47 Provide 'with implementationType' overloads
Provided overloaded versions of `forField` and `forMethodParameter` that
accept a `ResolvableType` implementation type (as opposed to a Class).

Primarily added to allow resolution against implementation types that
have been created programmatically using `forTypeWithGenerics`.

Issue: SPR-11218
2014-01-17 11:49:44 -08:00
Phillip Webb 7e6dbc24f6 Make TypeDescriptor more amenable to subclassing
Change the previously package scope TypeDescriptor constructor to
protected and add a getResolvableType() protected method.

Issue: SPR-11303
2014-01-17 11:05:40 -08:00
Rossen Stoyanchev e2feed494b Move "handlers" field to AbstractSubscribableChannel
Move the management of subscribers to the abstract parent class where
it belongs.
2014-01-17 11:24:28 -05:00
Rossen Stoyanchev 4e933b4765 Polish log messages 2014-01-17 11:03:02 -05:00
Sam Brannen 6e30851328 Improve logging in TransactionalTEL
This commit makes the logging in TransactionalTestExecutionListener
consistent for both starting and ending transactions. Specifically,
the current TestContext is now included in the informational log
statement when starting a new transaction.

Issue: SPR-11323
2014-01-17 14:54:36 +01:00
Brian Clozel 96b418cc8a Make RequestMappingHandlerMapping xml config easier
Prior to this commit, it was necessary to override
the HandlerMapping definition to change properties
like useSuffixPatternMatch, useSuffixPatternMatch...

This commits adds new attributes on the
mvc:annotation-driven XML tag that allows to configure
such flags:
* use-suffix-pattern-match
* use-trailing-slash-match
* use-registered-suffix-pattern-match

Issue: SPR-10163
2014-01-17 11:21:25 +01:00
Rossen Stoyanchev c1f3da082c Write prelude on successive SockJS streaming requests
sockjs-client expects a prelude to be written on every request with
streaming transports. The protocol tests don't make this clear and
don't expose this issue.

The test case for SPR-11183 (writing 20K messages in succession) did
expose the issue and this commit addresses it.

Issue: SPR-11183
2014-01-16 12:27:14 -05:00
Juergen Hoeller 6f5a7f65ac Polishing 2014-01-16 18:18:00 +01:00
Juergen Hoeller 4f45ad549e Introduced customizeConnection callbacks for URLConnection used by exists() / contentLength() / lastModified()
Issue: SPR-11320
2014-01-16 17:09:23 +01:00
Juergen Hoeller 6051ea8ae3 Polishing 2014-01-16 16:54:49 +01:00
Juergen Hoeller 838855b1aa Fixed accidental use of JDK 1.7+ Integer/Long.compare methods
Issue: SPR-11319
2014-01-16 16:54:40 +01:00
Juergen Hoeller 11bc9d0aeb Mentioned "-parameters" compiler flag in javadoc 2014-01-16 12:49:31 +01:00
Juergen Hoeller 05047d3a26 Declared JDK 6 update 18 as minimum requirement 2014-01-16 12:48:41 +01:00
Juergen Hoeller 799c6a63ec Fixed version number in xsd comment 2014-01-16 11:19:14 +01:00
Juergen Hoeller 50dfa037d0 Several ref doc fixes
Issue: SPR-8182
Issue: SPR-11243
Issue: SPR-11292
Issue: SPR-11318
2014-01-16 11:18:53 +01:00
Juergen Hoeller e2c6e637a4 Polishing 2014-01-16 00:04:20 +01:00
Juergen Hoeller 444b3720bc Added tests for context initializers on DispatcherServlet
Issue: SPR-11314
2014-01-16 00:04:07 +01:00
Juergen Hoeller 17cc63ef63 checkNotModified needs to consider HEAD as well
Issue: SPR-11317
2014-01-15 23:06:47 +01:00
Juergen Hoeller a5f9b29292 Polishing 2014-01-15 22:53:46 +01:00
Juergen Hoeller 91881ff036 Introduced "globalInitializerClasses" next to the existing "contextInitializerClasses", applying to FrameworkServlets as well
Issue: SPR-11314
2014-01-15 22:21:27 +01:00
Juergen Hoeller e670f4e5c6 Polishing 2014-01-15 17:45:04 +01:00
Juergen Hoeller 961f42bd43 Introduced "spring.getenv.ignore" system property for preventing System.getenv calls
Issue: SPR-11297
2014-01-15 17:44:17 +01:00
Juergen Hoeller ab15ed2a05 ObjectUtils.isCompatibleWithThrowsClause supports varargs now 2014-01-15 16:09:31 +01:00
Sam Brannen feb9d261ac Remove unused import in MockHttpServletRequestBuilderTests 2014-01-15 15:46:52 +01:00
Juergen Hoeller 76bb966b1a Removed Commons Lang references 2014-01-15 15:35:08 +01:00
Juergen Hoeller 8da9e5466a Turned ArgumentsMatchKind and ArgumentsMatchInfo to package-visible 2014-01-15 15:28:20 +01:00
Juergen Hoeller abff789b0f Removed javadoc references to non-accessible subclasses 2014-01-15 13:39:09 +01:00
Juergen Hoeller 5d06bcec70 Fixed getTypeDifferenceWeight algorithm in ReflectionHelper, and removed unused argsRequiringConversion storage
Issue: SPR-11306
2014-01-15 13:36:50 +01:00
Rossen Stoyanchev 5f2106046c Add UpgradeRequestStrategy for WildFly/Undertow
Issue: SPR-11237
2014-01-14 16:45:18 -05:00
Sam Brannen 5ee89a3021 Polish explanation of the 'default' profile
Issue: SPR-11256
2014-01-14 21:05:40 +01:00
Rossen Stoyanchev bac9f43b66 Fix typo in documentation
Issue: SPR-11301
2014-01-14 14:51:27 -05:00
Stephane Nicoll c9044151f5 Add explanation for the special 'default' profile
Better integrated explanation of the 'default' profile with both XML
and Java config examples showing the same thing.

Issue: SPR-11256
2014-01-14 14:32:50 -05:00
Erik van Paassen 070c5c3d33 Fixed a typo in RequestMappingHandlerMapping.java 2014-01-14 14:28:19 -05:00
Rossen Stoyanchev ea0825c0a6 Trim tokenized strings in websocket namespace
Issue: SPR-11307
2014-01-14 12:45:47 -05:00
Sam Brannen 2dfd69bbb3 Stop using deprecated junit.framework.Assert class 2014-01-14 18:19:06 +01:00
Rossen Stoyanchev 8b35c3ff74 Recognize Content-Type as special header in MHSRB
When adding headers generically, MockHttpServletRequestBuilder now
recognizes Content-Type and updates the contentType field accordingly.

Issue: SPR-11308
2014-01-14 12:11:12 -05:00
Juergen Hoeller 26271fc30c Polishing 2014-01-13 23:45:54 +01:00
Juergen Hoeller 1865361163 CronTriggerFactoryBean allows 'calendarName' and 'description' to be specified
Also making 'description' available on SimpleTriggerFactoryBean.

Issue: SPR-9771
(cherry picked from commit 7502ecd)
2014-01-13 23:44:45 +01:00
Rossen Stoyanchev a5c3143512 Allow hook to associate user with WebSocket session
This change adds a protected method to DefaultHandshakeHandler to
determine the user for the WebSocket session. By default it's
implemeted to obtain it from the request.

Issue: SPR-11228
2014-01-13 16:39:37 -05:00
Rossen Stoyanchev 6265bc1df7 Fall back on user in the Jetty UpgradeRequest
The Jetty ServletWebUpgradeRequest implements getUserPrincipal to
return the Principal from the HttpServletRequest on the upgrade.
This change ensures we can fall back on that.

However the JettyRequestUpgradeStrategy still passes the user from
HttpServletRequest from the upgrade, in order to work with Jetty
9.0.x and avoid running into this 9.1.x issue:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=423118
2014-01-13 16:39:37 -05:00
Juergen Hoeller 547646de6d Polishing 2014-01-13 22:25:34 +01:00
Juergen Hoeller f7fc2cbc3b Replaced reflection code with straight Servlet 3.0 setAsyncStarted call 2014-01-13 22:20:46 +01:00
Juergen Hoeller cdd65a70af Added compatibility note on WildFly 8 2014-01-13 22:14:51 +01:00
Juergen Hoeller 24d40fa3e0 Fixed resolveProxyTargetClass exception message 2014-01-13 22:14:27 +01:00
Juergen Hoeller bd87ff7f92 Removed TestGroup.LONG_RUNNING marker from Groovy and JRuby tests 2014-01-13 22:13:42 +01:00
Greg Turnquist 6b0d88721c Add method for HTTP PATCH in MockMvcRequestBuilders
Issue: SPR-11299

This is short to avoid having to use MockMvcRequestBuilders.request()
and instead have a simple patch(url, params...)
2014-01-13 14:17:16 -05:00
Rossen Stoyanchev 5068eb2e01 Add minor optimization to AbstractErrors
Issue: SPR-11304
2014-01-13 14:05:25 -05:00
Phillip Webb 9d928db3a8 Merge pull request #429 from VasylTretiakov/master
* pull429:
  Fix various documentation issues
2014-01-09 22:40:52 -08:00
Vasyl Tretiakov 37c9b26ff8 Fix various documentation issues
- Remove formatting that interferes with code highlighting
- Fix some XML syntax issues
- Added missing punctuation
2014-01-09 22:37:25 -08:00
Phillip Webb 9ed911075e Merge pull request #434 from snicoll/ascidoc-liveupdate
* ascidoc-liveupdate:
  Hard-wrap CONTRIBUTING-DOCUMENTATION at 90 chars
  Improve the "contributing documentation" readme
2014-01-09 16:35:55 -08:00
Phillip Webb 54805bc212 Hard-wrap CONTRIBUTING-DOCUMENTATION at 90 chars 2014-01-09 16:35:14 -08:00
Stephane Nicoll d2e5ec6736 Improve the "contributing documentation" readme
Update the "contributing documentation" readme to include the correct
gradle goal and provide a troubleshooting section.
2014-01-09 16:32:13 -08:00
Phillip Webb 2983e3ca31 Merge pull request #435 from snicoll/SPR-11280
* SPR-11280:
  Removed reference to Cactus from documentation
2014-01-09 16:18:15 -08:00
Stephane Nicoll 2afd9bc371 Removed reference to Cactus from documentation
Issue: SPR-11280
2014-01-09 16:17:21 -08:00
Arjen Poutsma cf6cf18f1a Corrected CatchAllConverter ordering docs
Corrected documentation regarding the CatchAllConverter in the XStream
javadocs.
2014-01-08 14:27:58 +01:00
Rossen Stoyanchev 4342497305 Add support for custom message converters
The Java and XML config for STOMP WebSocket applications now supports
configuring message converters.

Issue: SPR-11184
2014-01-07 16:16:29 -05:00
Rossen Stoyanchev 1fa4d9169f Upgrade to Tomcat 8 RC10 and remove unused repos 2014-01-06 15:24:37 -05:00
Phillip Webb f37d030860 Merge pull request #432 from kryger/master
* pull432:
  Removed extraneous character from the online documentation
2014-01-06 11:15:43 -08:00
Lukasz Kryger f3a08447fd Removed extraneous character from the online documentation 2014-01-06 11:15:19 -08:00
Sam Brannen a30cf3058e Remove unused imports in tests 2014-01-06 12:16:24 +01:00
Sam Brannen 27ab9332c1 Suppress deprecation warning for MHSR.setStatus()
Suppressing deprecation warnings for
MockHttpServletResponse.setStatus(int, String).
2014-01-06 12:15:52 +01:00
Juergen Hoeller 5d3484c74a Upgraded Tiles2 TilesContainer to Tiles 2.2.2 (following the Spring 4.0 baseline)
In sync with our Tiles3 TilesContainer implementation now, as far as possible.

Issue: SPR-11285
2014-01-06 00:19:36 +01:00
Juergen Hoeller 24030a3f61 Added deprecation log message and javadoc note for Quartz 1.x support
Issue: SPR-11262
2014-01-05 21:39:05 +01:00
Juergen Hoeller b228a06e07 Consistent support for setStartTime in CronTrigger(Factory)Bean and SimpleTrigger(Factory)Bean, and consistent declaration of varargs in scheduling.quartz package
Issue: SPR-10940
2014-01-05 17:30:42 +01:00
Juergen Hoeller 38a8ace5bb Full Quartz 2.2 support, including LocalDataSourceJobStore
While we've had basic Quartz 2.2 support before, a few details were missing:
* LocalDataSourceJobStore's ConnectionProvider adapters need to provide an empty implementation of Quartz 2.2's new initialize method.
* SchedulerFactoryBean's "schedulerContextMap" needs to be explicitly declared with String keys, otherwise it can't be compiled against Quartz 2.2 (forward compatibility once we're dropping Quartz 1.x support). This doesn't hurt against older Quartz versions either, since the keys need to be Strings anyway.

Issue: SPR-11284
2014-01-05 17:24:18 +01:00
Juergen Hoeller ee2022e54c Polishing 2014-01-05 03:01:44 +01:00
Juergen Hoeller a0ccd65d51 Consistent build dependencies 2014-01-05 03:00:12 +01:00
Juergen Hoeller 675b650290 Polishing 2014-01-05 00:16:01 +01:00
Juergen Hoeller 5661d3826c Fixed Jackson2ObjectMapperFactoryBean class name in javadoc examples 2014-01-05 00:15:33 +01:00
Juergen Hoeller 11b3fe2289 Added setModulesToInstall with convenient Class vararg, renamed setFindModules to setFindModulesViaServiceLoader, made existing setModules override any other setting
Issue: SPR-11040
2014-01-04 23:29:05 +01:00
Juergen Hoeller a2d40f3f16 Polishing 2014-01-04 22:48:06 +01:00
Juergen Hoeller 0de307bb65 Consistent equals/hashCode/toString implementations in AnnotationMatchingPointcut/ClassFilter/MethodMatcher
Issue: SPR-11275
Issue: SPR-11276
2014-01-04 22:47:33 +01:00
Phillip Webb 26f1e05ffc Upgrade to CGLIB 3.1 and Objenesis 2.1
Issue: SPR-11226
2014-01-03 14:15:19 -08:00
Juergen Hoeller 3948727b13 Polishing 2014-01-03 23:14:50 +01:00
Rossen Stoyanchev de280b01fe Support custom PathMatcher for MappedInterceptor's
Issue: SPR-11197
2014-01-03 16:44:01 -05:00
Rossen Stoyanchev abb8a93e2f Drop separate user dest property for subscriptions
Before this change DefaultUserDestinationResolver provided a separate
destination prefix property for identifying "user" destinations in
subscription requests as opposed to in sent messages. Such a separate
property should not be needed.

Issue: SPR-11263
2014-01-03 16:44:01 -05:00
Rossen Stoyanchev d0556e61f9 Log stack trace on failure to send message to client
Issue: SPR-11201
2014-01-03 16:44:01 -05:00
Brian Clozel b9c8f47b01 Use OptionalValidatorFactoryBean in Configurers
Configurers and BeanDefinitionParsers should use
OptionalValidatorFactoryBean instead of
LocalValidatorFactoryBean.

The Optional implementation catches and logs setup
exceptions, useful when a validation API is present on
the classpath but not the actual implementation.

Issue: SPR-11272
2014-01-03 22:36:56 +01:00
Juergen Hoeller 3bed6cfc7c Activated through rename to *Tests, and added method call interaction tests
Issue: SPR-7831
2014-01-03 22:11:12 +01:00
Juergen Hoeller 640d8cb67f Consistent implementation of AsyncListenableTaskExecutor
Issue: SPR-11282
2014-01-03 21:57:07 +01:00
Juergen Hoeller 6a5a3c97ed Introduced OptionalValidatorFactoryBean for scenarios where the JSR-303 API is present but no Bean Validation Provider is available (used by the MVC namespace)
Issue: SPR-11272
2014-01-03 18:18:55 +01:00
Juergen Hoeller ff26dfdd28 Added cache for path pattern tokenization
Issue: SPR-11258
2014-01-03 17:33:46 +01:00
Juergen Hoeller 240819f955 Introduced "spring.beaninfo.ignore" system property for optimized Introspector usage
Issue: SPR-9014
(cherry picked from commit f88cbda)
2014-01-03 16:39:34 +01:00
Juergen Hoeller 8d1e55d101 Avoid hard reference to LocalValidatorFactoryBean in <mvc:annotation-driven> parser
Issue: SPR-11272
(cherry picked from commit c48da0d)
2014-01-03 16:38:22 +01:00
Juergen Hoeller 6aabb5f17e Support varargs for DomUtils.getChildElementsByTagName
Issue: SPR-11272
(cherry picked from commit e334489)
2014-01-03 16:18:48 +01:00
Brian Clozel 15d7d6d7ab Fix Validator initialization with a no-op implementation
Issue: SPR-11185
2014-01-03 16:02:57 +01:00
Brian Clozel 2c8f670d5f Support Validation in @MessageMapping annotated methods
Payload parameters in @MessageMapping annotated
methods can now also be validated when annotated
with a Validation annotation (@Valid, @Validated...).

A default Validator is registered by the MessageBroker
Configurer, but it is possible to provide a list of custom
validators as well.

Issue: SPR-11185
2014-01-03 15:25:33 +01:00
Brian Clozel 1c83e8653a Switch to Jackson 2 in unit tests
Prior to this commit, some unit tests were using
Spring's Jackson 1.x implementations. Now Jackson
2.x implementations are the default ones used in
unit tests.

Even if Jackson 1.x support is deprecated, Jackson 1.x
unit tests are kept.

Issue: SPR-11121
2014-01-03 09:50:43 +01:00
Rossen Stoyanchev ef13dbfcdd Handle bad STOMP messages in StompSubProtocolHandler
Issue: SPR-11277
2014-01-02 12:27:59 -05:00
Rossen Stoyanchev 1f49f994e6 Fix issue with use of SecureRandom for id generation
Switch to using nextBytes as generateSeed doesn't seem to be always
supported by all hardware providers.

Issue: SPR-11278
2014-01-02 12:06:37 -05:00
Rossen Stoyanchev 3b14e974f8 Remove unnecessary copying of headers in GenericMessage
Since the MessageHeaders constructor is makes a copy of the headers and
is protected against a null map, there is no need for the same to be
done in GenericMessage.

Issue: SPR-11268
2014-01-02 11:35:31 -05:00
Rossen Stoyanchev 12fe9174f0 Make ObjectMapper configurable in spring-messaging
Issue: SPR-11279
2014-01-02 11:27:18 -05:00
Juergen Hoeller 82ea9ece5c Refined logging to include target class for each transactional method name
Also simplified cache key 'hashCode' implementation, relying on 'equals' to differentiate between same method on different target classes.

Issue: SPR-11267
2014-01-01 18:36:48 +01:00
Juergen Hoeller f0d21510f5 Polishing
Issue: SPR-11259
2013-12-30 19:13:04 +01:00
Juergen Hoeller 5e00113c65 Added extensive default converters for JSR-310 value types
Also adding several further Joda-Time converters for consistency with JSR-310 converters.

Issue: SPR-11259
2013-12-30 19:10:34 +01:00
Juergen Hoeller 48909886a2 Added support for the Java 8 style 'from'/'to' method conventions
Also introduced a default ZonedDateTime-Calendar converter which is not covered by the default convention due to the 'from' method only being defined on GregorianCalendar.

Issue: SPR-11259
2013-12-30 19:08:36 +01:00
Juergen Hoeller 73d8f069fe EhCacheFactoryBean does not call set(Sampled)StatisticsEnabled on EhCache 2.7/2.8
Issue: SPR-11265
2013-12-30 12:52:35 +01:00
Juergen Hoeller 0657136605 Support for Jackson's findModules and autodetection of JSR-310 and Joda-Time support
Issue: SPR-11040
2013-12-29 21:52:58 +01:00
Juergen Hoeller 85921808b3 MappingJackson2(Http)MessageConverter logs warnings after canRead/canWrite checks
This change involves a general upgrade to Jackson 2.3 in our build.

Issue: SPR-11261
2013-12-29 21:50:43 +01:00
Juergen Hoeller 7f5d6ea3f9 Fixed NavigableSet/NavigableMap detection in createCollection/createMap
Issue: SPR-11257
2013-12-28 20:48:35 +01:00
Rossen Stoyanchev 4e5e700213 Add client login/passcode to broker relay
Issue: SPR-11154
2013-12-23 21:40:27 -05:00
Rossen Stoyanchev 0a12f28b58 Introduce StompReactorNettyTcpClient
Issue: SPR-11153
2013-12-23 21:40:27 -05:00
Rossen Stoyanchev 2e4f38f6af Introduce AbstractMockMvcBuilder class
This change splits out an abstract base class from DefaultMockMvcBuilder
with StandaloneMockMvcBuilder switching to extend the new abstract class
(rather than DefaultMockMvcBuilder).

Issue: SPR-11238
2013-12-23 21:40:27 -05:00
Juergen Hoeller e3017c30bb ResourceDatabasePopulator's setScripts takes varargs 2013-12-23 22:00:30 +01:00
Juergen Hoeller d032c20a54 Polishing
Issue: SPR-10469
2013-12-23 21:59:21 +01:00
Juergen Hoeller b4d6e27fb3 Upgraded embedded Derby support to 10.6+ and build to 10.10
Issue: SPR-10469
2013-12-23 21:58:42 +01:00
Juergen Hoeller 9a39f39b6f Polishing
Issue: SPR-11254
2013-12-23 12:49:57 +01:00
Juergen Hoeller ee5b7fdab8 Revised XMLEventStreamWriter to allow for empty elements with attributes
Issue: SPR-11254
2013-12-23 12:49:47 +01:00
Sam Brannen 710fdc73f1 Polish Javadoc for Groovy bean support classes 2013-12-21 14:00:47 +01:00
Juergen Hoeller f9e8eb59e1 Fixed hasUnresolvableGenerics() to return false in case of an unresolvable bounded variable as well
Issue: SPR-11250
2013-12-20 16:44:25 +01:00
Juergen Hoeller bc3064cbb7 Polishing 2013-12-20 01:28:40 +01:00
Juergen Hoeller a884cde18c Upgraded to JCache 1.0 RC1
Also completing 4.0's consistency efforts between Spring's cache adapters.
2013-12-20 01:28:16 +01:00
Juergen Hoeller b1460742c3 InjectionMetadata caching per bean name needs to refresh when bean class changes
Issue: SPR-11246
2013-12-19 23:49:31 +01:00
Juergen Hoeller 2faf008c2e Polishing
Issue: SPR-11225
2013-12-19 23:08:18 +01:00
Juergen Hoeller 11fb12b920 Fixed AbstractMessageConverterMethodArgumentResolver's type variable resolution
Issue: SPR-11225
2013-12-19 23:04:23 +01:00
Juergen Hoeller bfba53f958 Fixed handling of primitive vararg array in CacheOperationContext
Issue: SPR-11249
2013-12-19 19:15:57 +01:00
Juergen Hoeller cb682cd8b7 Revised BeanInfoFactory javadoc
Issue: SPR-9014
2013-12-19 15:10:27 +01:00
Juergen Hoeller aa2fadd8da Revised ResolvableType's handling of (self-referential) type variables
Also resolving at construction time now, and shortcutting assignability evaluation.

Issue: SPR-11219
2013-12-19 14:55:16 +01:00
Juergen Hoeller 260bbe319d Fixed accidental use of Java 8 getParameterCount(), plus polishing of related classes
Issue: SPR-11245
2013-12-18 18:08:32 +01:00
Juergen Hoeller 234272eb8f Polishing
Issue: SPR-11215
2013-12-17 21:39:40 +01:00
Juergen Hoeller 67abeb4722 SpEL performs String->String type conversion even within concatenated String
Issue: SPR-11215
2013-12-17 21:35:14 +01:00
Juergen Hoeller 63d300ac86 Polishing
Issue: SPR-11242
2013-12-17 20:14:33 +01:00
Juergen Hoeller 1d47fc6e2d Consistent non-declaration of serialVersionUID
Issue: SPR-11242
2013-12-17 20:14:07 +01:00
Juergen Hoeller 994efe45fd Prevented potential infinite recursion in hashCode/equals
Issue: SPR-11219
2013-12-17 20:12:03 +01:00
Juergen Hoeller 6183683041 Fixed typos
Issue: SPR-11232
Issue: SPR-11242
2013-12-17 18:26:23 +01:00
Juergen Hoeller 74c679eb2f Polishing 2013-12-17 18:21:04 +01:00
Juergen Hoeller 479d073f1b Adapted orm.hibernate4 and HibernateJpaVendorAdapter to avoid deprecation warnings on Hibernate 4.3 final
Issue: SPR-11240
2013-12-17 16:46:58 +01:00
Rossen Stoyanchev ff92f5af57 Fix typo
Issue: SPR-11241
2013-12-17 08:26:50 -05:00
Juergen Hoeller 2a3ca619f9 Polishing
Issue: SPR-11221
2013-12-17 12:40:21 +01:00
Juergen Hoeller 23546b1234 Moved AnnotationBeanNameGenerator's String value check right before cast
Issue: SPR-11221
2013-12-17 12:39:24 +01:00
Juergen Hoeller 078d2fe0e2 Added current version information to SpringAsmInfo's javadoc 2013-12-16 22:50:25 +01:00
Juergen Hoeller 105e176a80 Fixed @Bean meta-annotation detection when using ASM
This turned out to be a bug in the ASM-based AnnotationMetadata implementation where has/getAnnotatedMethods didn't consider meta-annotations., in contrast to its StandardAnnotationMetadata sibling.

Issue: SPR-10488
2013-12-16 22:47:43 +01:00
Juergen Hoeller 61a3d04e91 Set scoped proxy role to same role as target definition
This allows scoped proxy definitions to override regular application bean definitions (again).

Issue: SPR-11229
2013-12-16 21:47:35 +01:00
Juergen Hoeller e2f85fc1d0 Defensively detect non-empty String fields in @Scheduled
Issue: SPR-11223
2013-12-16 21:45:40 +01:00
Juergen Hoeller b6970d3504 Removed obsolete JBoss 5.x support code from JBossLoadTimeWeaver 2013-12-16 20:21:34 +01:00
Juergen Hoeller 8a3b4c69c8 Fixed primitive type assignability in BeanUtils.copyProperties
Issue: SPR-11231
2013-12-16 20:18:37 +01:00
Sam Brannen 9eb58b9596 Polish Javadoc for ScopedProxyMode 2013-12-13 18:45:34 +01:00
Sam Brannen 1c04dcbe17 Update readme.txt with current links 2013-12-13 18:00:06 +01:00
Sam Brannen 0b6bd46863 Polish reference manual 2013-12-13 15:58:45 +01:00
Sam Brannen f199d5187b Polish reference manual 2013-12-13 15:35:38 +01:00
Spring Buildmaster 569fbc9f39 Next development version 2013-12-11 23:15:29 -08:00
Phillip Webb 421292acf4 Final documentation polish before 4.0 2013-12-11 22:31:29 -08:00
Rossen Stoyanchev e637418010 Update stomp/websocket documentation 2013-12-11 23:36:55 -05:00
Rossen Stoyanchev f36863947d Update STOMP/WebSocket documentation 2013-12-11 21:18:06 -05:00
Juergen Hoeller 50b8a53415 What's New overhaul 2013-12-12 03:09:40 +01:00
Juergen Hoeller ca194261a4 Removed support for JBoss AS 5's VFS variant (since we require JBoss AS 6+ now) 2013-12-12 02:57:34 +01:00
Juergen Hoeller 21f680c861 Deprecated DefaultKeyGenerator
Issue: SPR-11210
2013-12-12 02:57:17 +01:00
Sam Brannen 6ee725031c Document meta-annotation support in the TCF
This commit documents meta-annotation support for test-related
annotations in the TestContext framework within the reference manual.

Issue: SPR-11109
2013-12-12 02:39:44 +01:00
Sam Brannen 341854fb56 Revised wording around “new in 3.2” 2013-12-12 01:53:29 +01:00
Sam Brannen 48ecf0af57 Do not format TestContext unless referring to class 2013-12-12 01:39:05 +01:00
Brian Clozel a9a20e297b changed Sun references and links to Oracle 2013-12-12 01:32:52 +01:00
Sam Brannen a83fb13fc4 Add Testing Improvements section to reference manual 2013-12-12 01:29:53 +01:00
Juergen Hoeller a3a43448d1 Polishing 2013-12-11 23:56:39 +01:00
Phillip Webb b085ec90b2 Replace references to VMware with Pivotal
Replace references to VMware in license, notices and maven generation
with Pivotal, Inc.

Issue: SPR-11073
2013-12-11 14:08:55 -08:00
Juergen Hoeller aa6e6c1349 Polishing 2013-12-11 22:58:23 +01:00
Juergen Hoeller 106a973a4d Prevent early FactoryBean creation for type checking purposes when coming from a factory method on yet another bean (e.g. from a configuration class)
Issue: SPR-11202
2013-12-11 22:57:22 +01:00
Phillip Webb b124066d63 Add What's new in 4.0 to reference documentation
Update the reference documentation with "What's new in Spring 4.0".
2013-12-11 13:52:49 -08:00
Brian Clozel 309fe9ceb1 Document MVC concepts introduced in Spring 4.0
Update the MVC reference documentation with the new concepts and classes
introduced in Spring 4.0
This reverts commit 6f874d734a2a38431c74444894f54797ecf74933.
2013-12-11 13:52:49 -08:00
Rossen Stoyanchev 01a78bbbac Add WebSocket reference documentation
Update reference documentation with a new section for Spring 4's
WebSocket support.
2013-12-11 13:52:48 -08:00
Brian Clozel 0a52c86559 Clean MVC reference documentation
Remove reference to removed deprecations and generally cleanup the MVC
documentation.
Cleanup Struts
2013-12-11 13:52:48 -08:00
Phillip Webb d6b4d92eed Clean reference docs and prepare for Spring 4
Polish and cleanup the asciidoc source and prepare the reference guide
for the upcoming Spring 4.0 release.
2013-12-11 13:52:48 -08:00
Brian Clozel 8b48ba2af3 Remove the What's new in Spring 3 from docs
Remove the entire What's new in Spring 3 section from the reference
documentation.
2013-12-11 13:52:47 -08:00
Phillip Webb 7e1e99d272 Extract appendix from main index.adoc
Extract the appendix into a separate asciidoc file in order to make the
main index.adoc easier to work with.
2013-12-11 13:52:47 -08:00
Juergen Hoeller bc5affa79a Made BeanUtils.copyProperties defensive about property type mismatches
Issue: SPR-11209
2013-12-11 20:49:18 +01:00
Rossen Stoyanchev 92dad1849f Rename @[Path/Destination]Variable in spring-messaging
Issue: SPR-11208
2013-12-11 14:44:57 -05:00
Juergen Hoeller a9605a11e9 "acceptExisting" flag allows for sharing per cacheManagerName on EhCache 2.5+
As a benefit over the "shared" flag, this allows for sharing a specific CacheManager in a system with potentially multiple CacheManagers involved, and it supports controlled shutdown by the EhCacheManagerFactoryBean that actually created the CacheManager.

Issue: SPR-11178
2013-12-11 17:25:02 +01:00
Juergen Hoeller 9c157ea073 DispatcherPortlet never uses a resource forward on Liferay
Issue: SPR-10791
2013-12-11 16:41:11 +01:00
Juergen Hoeller 8d6d6be39a MBean registration happens in a fully synchronized fashion for consistent results
Issue: SPR-11002
2013-12-11 16:31:26 +01:00
Juergen Hoeller 1b4e02b178 RequiredAnnotationBeanPostProcessor skips factory-bean definitions
Also moving the associated unit tests to the correct package beans.factory.annotation

Issue: SPR-10458
2013-12-11 16:11:16 +01:00
Juergen Hoeller 161819f141 Component scanning ignores attributes and meta-annotations on non-public annotations
Issue: SPR-11091
2013-12-11 15:29:55 +01:00
Sam Brannen a223e247c2 Document meta-annotation support in the TCF
- Completed Javadoc for MetaAnnotationUtils.
- Added Javadoc notes to multiple annotations in the TCF, pointing out
  which annotations can be used as meta-annotations.

Issue: SPR-11109
2013-12-11 14:43:10 +01:00
Juergen Hoeller 9fbb57c3ec Fixed CGLIB class validation to not raising warning for static final methods
Issue: SPR-11107
2013-12-11 12:34:59 +01:00
Juergen Hoeller 3ff3805ed6 Fixed extractOutputParameters to properly extract ResultSet in all cases
Issue: SPR-11076
2013-12-11 12:28:54 +01:00
Juergen Hoeller ccafccbec8 Actually accept String expressions for "prefetch" and "receive-timeout" in jms namespace
Issue: SPR-10986
2013-12-11 12:05:00 +01:00
Juergen Hoeller 2d2226baf6 Added 546 to Sybase data integrity violation codes
Issue: SPR-11097
2013-12-11 12:01:53 +01:00
Juergen Hoeller 62ea627965 Revised exclusion of java.lang.Class properties
Issue: SPR-11098
2013-12-11 11:58:46 +01:00
Phillip Webb a1529d498e Fix possible GenericMsgTemplate race condition
Fix a potential race condition with GenericMessagingTemplate's inner
TemporaryReplyChannel class.

Prior to this commit the `hasReceived` member variable was read after
calling `replyLatch.countDown()`.

Issue: SPR-11206
2013-12-11 00:08:34 -08:00
Phillip Webb f57c4a09ee Polish 2013-12-10 21:13:11 -08:00
Sam Brannen da7ae4a63b Polish meta-annotation terminology in MetaAnnoUtils 2013-12-11 02:14:50 +01:00
Sam Brannen 800018a817 Do not repopulate RequestContextHolder in ServTEL
This commit fixes a bug introduced in the last commit.

ServletTestExecutionListener (STEL) now tracks whether it has already
populated the RequestContextHolder.

Issue: SPR-11144
2013-12-11 01:00:04 +01:00
Sam Brannen 099b10d23b Honor presence of @WebAppConfiguration in ServTEL
The previous commit for issue SPR-11144 revealed a bug in
ServletTestExecutionListener (STEL). Specifically, STEL acted on the
fact that the ApplicationContext for a given TestContext was an
instance of WebApplicationContext. This behavior could potentially
break test code from previous releases of the Spring Framework that
relied on a custom setup of the RequestAttributes in the
RequestContextHolder with a custom WebApplicationContext ContextLoader.

This commit addresses this issue by ensuring that STEL only comes into
play if the test class is annotated with @WebAppConfiguration (for
prepareTestInstance() and beforeTestMethod()) or if the TestContext
attribute named RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE is set to
Boolean.TRUE (for afterTestMethod()).

Issue: SPR-11144
2013-12-10 23:49:58 +01:00
Juergen Hoeller c5d797736b Added tests for custom qualifier annotations on scoped @Bean methods
Issue: SPR-11116
2013-12-10 22:35:34 +01:00
Juergen Hoeller cb624e25c5 Fixed ExtendedBeanInfo and its tests to accept JDK 8 b117+ introspection results
Specifically, read and write methods are allowed to express property types with superclass/subclass relationships in both directions now.

Issue: SPR-11139
2013-12-10 22:34:17 +01:00
Juergen Hoeller 92816492ed Established well-defined registration order for Hibernate package scanning
Issue: SPR-7742
2013-12-10 16:47:17 +01:00
Juergen Hoeller eb1b3c5a68 Use bean-creating factory's AutowireCandidateResolver even for dependencies in parent factory
Specifically, if the current factory has Qualifier/ContextAnnotationAutowireCandidateResolver set up, it is important to pass it on to ancestor factories to get consistent qualifier matching results.

Issue: SPR-10966
2013-12-10 15:33:57 +01:00
Juergen Hoeller be63c07b2e Polishing 2013-12-10 13:26:52 +01:00
Juergen Hoeller d6e84631f5 Fixed @since tag 2013-12-10 13:26:42 +01:00
Juergen Hoeller 4fe52d1953 Polishing 2013-12-10 12:00:32 +01:00
Juergen Hoeller 6d7ce439b1 Introduced GuavaCacheManager as an alternative to ConcurrentMapCacheManager 2013-12-10 11:59:35 +01:00
Juergen Hoeller 4c8a7899f2 Optimized use of JDBC 3.0 ParameterMetaData.getParameterType, caching information about drivers which do not support that feature
Issue: SPR-11100
2013-12-10 01:38:57 +01:00
Juergen Hoeller 26d143868f Compatibility with XStream 1.4.5
XStream 1.4.5 doesn't check a given ConverterLookup for a ConverterRegistry implementation anymore, so we have to manually perform that check and assignment.

Issue: SPR-11147
2013-12-09 22:47:16 +01:00
Juergen Hoeller 242ecdc448 Fixed inner bean name determination for multi-level nesting scenario, calculating a unique bean name as early as possible now (and for any kind of bean scope)
Our per-bean caching in AutowiredAnnotationBeanPostProcessor and co relies on unique bean names, so this change fixes potential cache mismatch problems occuring there.

Issue: SPR-11131
2013-12-09 21:45:44 +01:00
Juergen Hoeller 5dcd28761c Fixed type resolution for uninitialized factory-method declaration
Issue: SPR-11112
2013-12-09 18:53:27 +01:00
Sam Brannen a3b022aa48 Ensure ServTEL doesn't reset ReqAttrs by accident
Prior to this commit, the ServletTestExecutionListener did not
overwrite RequestAttributes in the RequestContextHolder if the
ApplicationContext associated with the given TestContext was not a
WebApplicationContext; however, the ServletTestExecutionListener would
clear the RequestAttributes after every test method execution,
regardless of whether the context was a WebApplicationContext or not.
This behavior breaks backwards compatibility with integration tests
that managed the RequestAttributes in RequestContextHolder themselves.

This commit addresses this issue by introducing a TestContext attribute
named RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE in
ServletTestExecutionListener. This attribute is used internally within
ServletTestExecutionListener to ensure that the RequestContextHolder is
only cleared (i.e., reset) if the ServletTestExecutionListener actually
populated the RequestContextHolder.

Issue: SPR-11144
2013-12-09 15:35:54 +01:00
Rossen Stoyanchev 5f38996cd6 Add methods for static resolution of @ExceptionHandler 2013-12-09 08:19:17 -05:00
Juergen Hoeller 6078c27e60 Fixed evaluation of "!" operator in case of multiple profile expressions
Issue: SPR-11093
2013-12-09 13:29:21 +01:00
Juergen Hoeller f70739430b Polishing 2013-12-08 23:27:31 +01:00
Juergen Hoeller 8580d2d19e Fixed detection of generic types and qualifier annotations on scoped-proxy factory methods
Issue: SPR-11116
2013-12-08 23:24:16 +01:00
Juergen Hoeller 1f9b833c4d Introduced SockJsSession interface and moved SockJsSessionFactory and SockJsServiceConfig to sockjs.transport; added initialize(SockJsServiceConfig) method to TransportHandler interface; extracted TransportHandlingSockJsService from DefaultSockJsService; moved sockjs.support.frame to sockjs.frame and extracted (Default)SockJsFrameFormat from SockJsFrame; moved SockJsHttpRequestHandler to sockjs.support; removed Jackson 1.x support 2013-12-08 01:25:52 +01:00
Rossen Stoyanchev fcecd0328a Collapse messaging.simp.handler into messaging.simp 2013-12-06 17:23:31 -05:00
Rossen Stoyanchev 307bf4bede Add messaging.simp.user package 2013-12-06 17:05:29 -05:00
Rossen Stoyanchev 89455c00f6 Create messaging.simp.broker package 2013-12-06 16:24:04 -05:00
Juergen Hoeller ea8a2095ec Polishing 2013-12-06 21:51:18 +01:00
Juergen Hoeller 7a154e8e98 Renamed handler.support to handler.invocation 2013-12-06 21:50:47 +01:00
Juergen Hoeller c4163c7475 Moved messaging.support.converter to messaging.converter; moved messaging.support.tcp to messaging.tcp; moved messaging.support.channel to messaging.support itself; moved handler.condition to handler itself; reworked handler.method into handler.support 2013-12-06 18:24:38 +01:00
Rossen Stoyanchev 947f3d4b2b Update Javadoc, add tests and polish spring-messaging 2013-12-05 21:30:52 -05:00
Sam Brannen 3e0b0f100c Delete unused import in MockAsyncContext 2013-12-05 21:48:49 +01:00
Sam Brannen 4957131a7b Delete sysout.println call from MBean*Tests 2013-12-05 20:40:09 +01:00
Juergen Hoeller edeb11c556 Polishing 2013-12-04 23:58:05 +01:00
Brian Clozel efc5074395 Document ControllerAdvice annotation
Issue: SPR-11149
2013-12-04 17:14:55 +01:00
Spring Buildmaster 0912be105a Increment version to 4.0.0.BUILD-SNAPSHOT 2013-12-03 15:09:47 -08:00
1682 changed files with 80642 additions and 49160 deletions
+30 -7
View File
@@ -1,28 +1,51 @@
= How to contribute to the reference
The Spring Framework reference now uses http://asciidoctor.org/[asciidoctor]. This document describes how to contribute documentation updates.
The Spring Framework reference now uses http://asciidoctor.org/[asciidoctor]. This
document describes how to contribute documentation updates.
== Building with Gradle
You can build the documentation using gradle using the `asciidoc` task. For example, from the project root execute the following command:
You can build the documentation using gradle using the `reference` task. For example, from
the project root execute the following command:
gradlew asciidoc
./gradlew reference
the output will be available at `spring-framework/build/asciidoc/index.html`
the output will be available at `spring-framework/build/reference/htmlsingle/index.html`
== Live editing
One of the nice features about using asciidoctor is the support for live editing.
You will find a Guardfile already present at `spring-framework/src/asciidoc/Guardfile`. Then ensure to follow the setup instructions within the http://asciidoctor.org/docs/editing-asciidoc-with-live-preview/[Editing AsciiDoc with Live Preview] document.
You will find a Guardfile already present at `spring-framework/src/asciidoc/Guardfile`.
Make sure first to follow the setup instructions within the
http://asciidoctor.org/docs/editing-asciidoc-with-live-preview/[Editing AsciiDoc with Live Preview]
document. Once you have done that, there are additional gems to install to make it work
(assuming that you are using http://livereload.com/[LiveReload]):
When running `guard start` within the `src/asciidoc/` folder, any changes to the `src/asciidoc/index.adoc` file will automatically be written at `src/asciidoc/build/index.html`.
gem install guard-rspec guard-livereload
When running `guard start` within the `src/asciidoc/` folder, any changes to the
`src/asciidoc/index.adoc` file will automatically be written at
`src/asciidoc/build/index.html`.
== Troubleshooting
* If you are using LiveReload, make sure to select _Allow access to file URLs_ in the
LiveEdit plugin options of your browser.
* The icon used to enable _LiveReload_ can be a bit confusing. The dot is empty when it is
disabled and full when the plugin is active. Make sure to enable it on the tab
displaying the `index.html` file.
* Ensure you are _not_ running guard start at all as two instances could not run at the
same time. To exit a current session in a clean way, just type e in the shell.
== Documentation notes
Some notes on documentation
* It is important to keep whitespaces to a minimum to make it simple to edit files. This means use an editor with line wrapping rather than manually inserting hard returns.
* Documentation is wrapped at 90 chars, ensure that you manually wrap your edits
* Tabs are used for indentation, do not use spaces
* Follow the existing style when inserting `source` blocks
* http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/[Asciidoctor Quick Reference]
* http://asciidoctor.org/docs/user-manual/[Asciidoctor Manual]
* http://asciidoctor.org/docs/asciidoc-writers-guide/[Asciidoctor Writers Guide]
+76 -70
View File
@@ -1,33 +1,28 @@
_Have something you'd like to contribute to the framework? We welcome pull
requests, but ask that you carefully read this document first to understand how
requests but ask that you carefully read this document first to understand how
best to submit them; what kind of changes are likely to be accepted; and what
to expect from the Spring team when evaluating your submission._
_Please refer back to this document as a checklist before issuing any pull
request; this will save time for everyone!_
## Understand the basics
## Take Your First Steps
Not sure what a pull request is, or how to submit one? Take a look at GitHub's
### Understand the basics
Not sure what a pull request is, or how to submit one? Take a look at GitHub's
excellent [help documentation][] first.
## Search JIRA first; create an issue if necessary
### Search JIRA first; create an issue if necessary
Is there already an issue that addresses your concern? Do a bit of searching
in our [JIRA issue tracker][] to see if you can find something similar. If not,
please create a new issue before submitting a pull request unless the change is
truly trivial, e.g. typo fixes, removing compiler warnings, etc.
Is there already an issue that addresses your concern? Do a bit of searching
in our [JIRA issue tracker][] to see if you can find something similar. If you
do not find something similar, please create a new JIRA issue before submitting
a pull request unless the change is truly trivial -- for example: typo fixes,
removing compiler warnings, etc.
## Discuss non-trivial contribution ideas with committers
If you're considering anything more than correcting a typo or fixing a minor
bug, please discuss it on the [spring-framework-contrib][] mailing list before
submitting a pull request. We're happy to provide guidance, but please spend an
hour or two researching the subject on your own including searching the mailing
list for prior discussions.
## Sign the Contributor License Agreement
### Sign the Contributor License Agreement
If you have not previously done so, please fill out and submit the
[SpringSource CLA form][]. You'll receive a token when this process is complete.
@@ -42,29 +37,34 @@ your pull request:
I have signed and agree to the terms of the SpringSource Individual
Contributor License Agreement.
You do not need to include your token/id. Please add the statement above to all
You do not need to include your token/id. Please add the above statement to all
future pull requests as well, simply so that the Spring Framework team knows
immediately that this process is complete.
## Create a Branch
## Create your branch from `master`
### Branch from `master`
Master currently represents work toward Spring Framework 4.0. Please submit
all pull requests there, even bug fixes and minor improvements. Backports to
`3.2.x` will be considered on a case-by-case basis.
## Use short branch names
### Use short branch names
Branches used when submitting pull requests should preferably be named
according to JIRA issues, e.g. 'SPR-1234'. Otherwise, use succinct, lower-case,
dash (-) delimited names, such as 'fix-warnings', 'fix-typo', etc. In
[fork-and-edit][] cases, the GitHub default 'patch-1' is fine as well. This is
important, because branch names show up in the merge commits that result from
accepting pull requests, and should be as expressive and concise as possible.
accepting pull requests and should be as expressive and concise as possible.
## Use Spring Framework Code Style
## Mind the whitespace
The complete [Spring Framework Code Style][] reference is available on the wiki, but
here's a quick summary:
### Mind the whitespace
Please carefully follow the whitespace and formatting conventions already
present in the framework.
@@ -76,16 +76,16 @@ present in the framework.
1. Aim to wrap code at 90 characters, but favor readability over wrapping
1. Preserve existing formatting; i.e. do not reformat code for its own sake
1. Search the codebase using `git grep` and other tools to discover common
naming conventions, etc.
naming conventions, etc.
1. Latin-1 (ISO-8859-1) encoding for Java sources; use `native2ascii` to convert
if necessary
if necessary
## Add Apache license header to all new classes
### Add Apache license header to all new classes
```java
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -103,24 +103,24 @@ present in the framework.
package ...;
```
## Update Apache license header to modified files as necessary
### Update Apache license header in modified files as necessary
Always check the date range in the license header. For example, if you've
modified a file in 2013 whose header still reads
modified a file in 2014 whose header still reads:
```java
* Copyright 2002-2011 the original author or authors.
```
then be sure to update it to 2013 appropriately
Then be sure to update it to 2014 accordingly:
```java
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
```
## Use @since tags for newly-added public API types and methods
### Use @since tags for newly-added public API types and methods
e.g.
For example:
```java
/**
@@ -132,11 +132,13 @@ e.g.
*/
```
## Submit JUnit test cases for all behavior changes
## Prepare Your Commit
Search the codebase to find related unit tests and add additional @Test methods
within. It is also acceptable to submit test cases on a per JIRA issue basis,
e.g.
### Submit JUnit test cases for all behavior changes
Search the codebase to find related tests and add additional `@Test` methods
as appropriate. It is also acceptable to submit test cases on a per JIRA issue
basis, for example:
```java
package org.springframework.beans.factory.support;
@@ -161,15 +163,15 @@ public class Spr8954Tests {
```
## Squash commits
### Squash commits
Use `git rebase --interactive`, `git add --patch` and other tools to "squash"
multiple commits into atomic changes. In addition to the man pages for git,
there are many resources online to help you understand how these tools work.
Here is one: http://book.git-scm.com/4_interactive_rebasing.html.
Use `git rebase --interactive --autosquash`, `git add --patch`, and other tools
to "squash" multiple commits into a single atomic commit. In addition to the man
pages for git, there are many resources online to help you understand how these
tools work. The [Rewriting History section of Pro Git][] provides a good overview.
## Use real name in git commits
### Use real name in git commits
Please configure git to use your real first and last name for any commits you
intend to submit as pull requests. For example, this is not acceptable:
@@ -181,26 +183,26 @@ submitted against the SpringSource contributor license agreement:
Author: First Last <user@mail.com>
This helps ensure traceability against the CLA, and also goes a long way to
This helps ensure traceability against the CLA and also goes a long way to
ensuring useful output from tools like `git shortlog` and others.
You can configure this globally via the account admin area GitHub (useful for
fork-and-edit cases); globally with
You can configure this via the account admin area in GitHub (useful for
fork-and-edit cases); _globally_ on your machine with
git config --global user.name "First Last"
git config --global user.email user@mail.com
or locally for the spring-framework repository only by omitting the '--global'
flag:
or _locally_ for the `spring-framework` repository only by omitting the
'--global' flag:
cd spring-framework
git config user.name "First Last"
git config user.email user@mail.com
## Format commit messages
### Format commit messages
Please read and follow the [commit guidelines section of Pro Git][].
Please read and follow the [Commit Guidelines section of Pro Git][].
Most importantly, please format your commit messages in the following way
(adapted from the commit template in the link above):
@@ -225,31 +227,33 @@ Most importantly, please format your commit messages in the following way
1. Use imperative statements in the subject line, e.g. "Fix broken Javadoc link"
1. Begin the subject line sentence with a capitalized verb, e.g. "Add, Prune,
Fix, Introduce, Avoid, etc."
1. Begin the subject line with a capitalized verb, e.g. "Add, Prune, Fix,
Introduce, Avoid, etc."
1. Do not end the subject line with a period
1. Keep the subject line to 50 characters or less if possible
1. Restrict the subject line to 50 characters or less if possible
1. Wrap lines in the body at 72 characters or less
1. Mention associated JIRA issue(s) at the end of the commit comment, prefixed
with "Issue: " as above
with "Issue: " as above
1. In the body of the commit message, explain how things worked before this
commit, what has changed, and how things work now
commit, what has changed, and how things work now
For examples of this style, issue a `git log --author=cbeams` in the
spring-framework git repository. For convenience, here are several such commits:
`spring-framework` git repository. For convenience, here are several such commits:
https://github.com/SpringSource/spring-framework/commit/08e2669b84ec0faa2f7904441fe39ac70b65b078
https://github.com/SpringSource/spring-framework/commit/1d9d3e6ff79ce9f0eca03b02cd1df705925575da
https://github.com/SpringSource/spring-framework/commit/8e0b1c3a5f957af3049cfa0438317177e16d6de6
https://github.com/SpringSource/spring-framework/commit/b787a68f2050df179f7036b209aa741230a02477
- https://github.com/spring-projects/spring-framework/commit/08e2669b84ec0faa2f7904441fe39ac70b65b078
- https://github.com/spring-projects/spring-framework/commit/1d9d3e6ff79ce9f0eca03b02cd1df705925575da
- https://github.com/spring-projects/spring-framework/commit/8e0b1c3a5f957af3049cfa0438317177e16d6de6
- https://github.com/spring-projects/spring-framework/commit/b787a68f2050df179f7036b209aa741230a02477
## Run all tests prior to submission
## Run the Final Checklist
See the [building from source][] section of the README for instructions. Make
### Run all tests prior to submission
See the [building from source][] section of the `README` for instructions. Make
sure that all tests pass prior to submitting your pull request.
## Submit your pull request
### Submit your pull request
Subject line:
@@ -261,7 +265,7 @@ In the body:
1. Explain your use case. What led you to submit this change? Why were existing
mechanisms in the framework insufficient? Make a case that this is a
general-purpose problem and that yours is a general-purpose solution, etc.
1. Add any additional information and ask questions; start a conversation, or
1. Add any additional information and ask questions; start a conversation or
continue one from JIRA
1. Mention the JIRA issue ID
1. Also mention that you have submitted the CLA as described above
@@ -272,12 +276,12 @@ the commit message. This is fine, but please also include the items above in the
body of the request.
## Mention your pull request on the associated JIRA issue
### Mention your pull request on the associated JIRA issue
Add a comment to the associated JIRA issue(s) linking to your new pull request.
## Expect discussion and rework
### Expect discussion and rework
The Spring team takes a very conservative approach to accepting contributions to
the framework. This is to keep code quality and stability as high as possible,
@@ -289,13 +293,15 @@ strongly recommend discussing any serious submissions with the Spring Framework
team _prior_ to engaging in serious development work.
Note that you can always force push (`git push -f`) reworked / rebased commits
against the branch used to submit your pull request. i.e. you do not need to
issue a new pull request when asked to make changes.
against the branch used to submit your pull request. In other words, you do not
need to issue a new pull request when asked to make changes.
[help documentation]: http://help.github.com/send-pull-requests
[JIRA issue tracker]: https://jira.springsource.org/browse/SPR
[JIRA issue tracker]: https://jira.spring.io/browse/SPR
[spring-framework-contrib]: https://groups.google.com/forum/#!forum/spring-framework-contrib
[SpringSource CLA form]: https://support.springsource.com/spring_committer_signup
[fork-and-edit]: https://github.com/blog/844-forking-with-the-edit-button
[commit guidelines section of Pro Git]: http://progit.org/book/ch5-2.html#commit_guidelines
[building from source]: https://github.com/SpringSource/spring-framework#building-from-source
[Spring Framework Code Style]: https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Code-Style
[Rewriting History section of Pro Git]: http://git-scm.com/book/en/Git-Tools-Rewriting-History
[Commit Guidelines section of Pro Git]: http://git-scm.com/book/en/Distributed-Git-Contributing-to-a-Project#Commit-Guidelines
[building from source]: https://github.com/spring-projects/spring-framework#building-from-source
+37 -37
View File
@@ -7,10 +7,10 @@ can focus on application-level business logic, without unnecessary ties to
specific deployment environments.
The framework also serves as the foundation for [Spring Integration][], [Spring
Batch][] and the rest of the Spring [family of projects][]. Browse the
repositories under the [SpringSource organization][] on GitHub for a full list.
Batch][] and the rest of the Spring [family of projects][]. Browse the repositories
under the [Spring organization][] on GitHub for a full list.
## Downloading artifacts
## Downloading Artifacts
See [downloading Spring artifacts][] for Maven repository information. Unable to
use Maven or other transitive dependency management tools? See [building a
distribution with dependencies][].
@@ -18,7 +18,7 @@ distribution with dependencies][].
## Documentation
See the current [Javadoc][] and [reference docs][].
## Getting support
## Getting Support
Check out the [Spring forums][] and the [spring][spring tag] and
[spring-mvc][spring-mvc tag] tags on [Stack Overflow][]. [Commercial support][]
is available too.
@@ -30,30 +30,29 @@ bug? Please consider submitting a reproduction project via the
[spring-framework-issues][] GitHub repository. The [readme][] there provides
simple step-by-step instructions.
## Building from source
## Building from Source
The Spring Framework uses a [Gradle][]-based build system. In the instructions
below, [`./gradlew`][] is invoked from the root of the source tree and serves as
a cross-platform, self-contained bootstrap mechanism for the build.
### prerequisites
### Prerequisites
[Git][] and [OpenJDK 8 early access build 100 or later][JDK8 build]
Be sure that your `JAVA_HOME` environment variable points to the `jdk1.8.0` folder
extracted from the JDK download.
### check out sources
`git clone git://github.com/SpringSource/spring-framework.git`
### Check out sources
`git clone git@github.com:spring-projects/spring-framework.git`
### import sources into your IDE
### Import sources into your IDE
Run `./import-into-eclipse.sh` or read `import-into-idea.md` as appropriate.
> **Note:** Per the prerequisites above, ensure that you have JDK 8 configured
properly in your IDE.
> **Note:** Per the prerequisites above, ensure that you have JDK 8 configured properly in your IDE.
### install all spring-\* jars into your local Maven cache
### Install all spring-\* jars into your local Maven cache
`./gradlew install`
### compile and test, build all jars, distribution zips and docs
### Compile and test; build all jars, distribution zips, and docs
`./gradlew build`
... and discover more commands with `./gradlew tasks`. See also the [Gradle
@@ -62,40 +61,41 @@ build and release FAQ][].
## Contributing
[Pull requests][] are welcome; see the [contributor guidelines][] for details.
## Staying in touch
Follow [@springframework][] and its [team members][] on Twitter. In-depth
articles can be found at the SpringSource [team blog][], and releases are
announced via our [news feed][].
## Staying in Touch
Follow [@SpringCentral][] as well as [@SpringFramework][] and its [team members][]
on Twitter. In-depth articles can be found at [The Spring Blog][], and releases
are announced via our [news feed][].
## License
The Spring Framework is released under version 2.0 of the [Apache License][].
[Spring Integration]: https://github.com/SpringSource/spring-integration
[Spring Batch]: https://github.com/SpringSource/spring-batch
[family of projects]: http://springsource.org/projects
[SpringSource organization]: https://github.com/SpringSource
[downloading Spring artifacts]: https://github.com/SpringSource/spring-framework/wiki/Downloading-Spring-artifacts
[building a distribution with dependencies]: https://github.com/SpringSource/spring-framework/wiki/Building-a-distribution-with-dependencies
[Javadoc]: http://static.springsource.org/spring-framework/docs/current/javadoc-api
[reference docs]: http://static.springsource.org/spring-framework/docs/current/spring-framework-reference
[Spring forums]: http://forum.springsource.org
[Spring Integration]: https://github.com/spring-projects/spring-integration
[Spring Batch]: https://github.com/spring-projects/spring-batch
[family of projects]: http://spring.io/projects
[Spring organization]: https://github.com/spring-projects
[downloading Spring artifacts]: https://github.com/spring-projects/spring-framework/wiki/Downloading-Spring-artifacts
[building a distribution with dependencies]: https://github.com/spring-projects/spring-framework/wiki/Building-a-distribution-with-dependencies
[Javadoc]: http://docs.spring.io/spring-framework/docs/current/javadoc-api/
[reference docs]: http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/
[Spring forums]: http://forum.spring.io/
[spring tag]: http://stackoverflow.com/questions/tagged/spring
[spring-mvc tag]: http://stackoverflow.com/questions/tagged/spring-mvc
[Stack Overflow]: http://stackoverflow.com/faq
[Commercial support]: http://springsource.com/support/springsupport
[Spring Framework JIRA]: http://jira.springsource.org/browse/SPR
[the lifecycle of an issue]: https://github.com/cbeams/spring-framework/wiki/The-Lifecycle-of-an-Issue
[spring-framework-issues]: https://github.com/SpringSource/spring-framework-issues#readme
[readme]: https://github.com/SpringSource/spring-framework-issues#readme
[Commercial support]: http://spring.io/services
[Spring Framework JIRA]: https://jira.spring.io/browse/SPR
[the lifecycle of an issue]: https://github.com/spring-projects/spring-framework/wiki/The-Lifecycle-of-an-Issue
[spring-framework-issues]: https://github.com/spring-projects/spring-framework-issues#readme
[readme]: https://github.com/spring-projects/spring-framework-issues#readme
[Gradle]: http://gradle.org
[`./gradlew`]: http://vimeo.com/34436402
[Git]: http://help.github.com/set-up-git-redirect
[JDK8 build]: http://jdk8.java.net/download.html
[Gradle build and release FAQ]: https://github.com/SpringSource/spring-framework/wiki/Gradle-build-and-release-FAQ
[Gradle build and release FAQ]: https://github.com/spring-projects/spring-framework/wiki/Gradle-build-and-release-FAQ
[Pull requests]: http://help.github.com/send-pull-requests
[contributor guidelines]: https://github.com/SpringSource/spring-framework/blob/master/CONTRIBUTING.md
[@springframework]: http://twitter.com/springframework
[team members]: http://twitter.com/springframework/team/members
[team blog]: http://blog.springsource.org
[news feed]: http://www.springsource.org/news-events
[contributor guidelines]: https://github.com/spring-projects/spring-framework/blob/master/CONTRIBUTING.md
[@SpringFramework]: https://twitter.com/springframework
[@SpringCentral]: https://twitter.com/springcentral
[team members]: https://twitter.com/springframework/team/members
[The Spring Blog]: http://spring.io/blog/
[news feed]: http://spring.io/blog/category/news
[Apache License]: http://www.apache.org/licenses/LICENSE-2.0
+337 -257
View File
@@ -1,24 +1,44 @@
buildscript {
repositories {
maven { url "http://repo.springsource.org/plugins-release" }
maven { url "https://repo.spring.io/plugins-release" }
}
dependencies {
classpath("org.springframework.build.gradle:propdeps-plugin:0.0.5")
classpath("org.springframework.build.gradle:propdeps-plugin:0.0.7")
classpath("org.asciidoctor:asciidoctor-gradle-plugin:0.7.0")
classpath("org.springframework.build.gradle:docbook-reference-plugin:0.2.8")
}
}
ext {
moduleProjects = subprojects.findAll {
!it.name.equals('spring-build-src') && !it.name.equals('spring-framework-bom')
}
}
configure(allprojects) { project ->
group = "org.springframework"
version = qualifyVersionIfNecessary(version)
ext.aspectjVersion = "1.8.0.M1"
ext.groovyVersion = "1.8.9"
ext.hsqldbVersion = "2.3.1"
ext.junitVersion = "4.11"
ext.slf4jVersion = "1.6.1"
ext.jettyVersion = "9.1.0.v20131115"
ext.aspectjVersion = "1.8.4"
ext.eclipseLinkVersion = "2.4.2"
ext.groovyVersion = "1.8.9"
ext.hibernate3Version = "3.6.10.Final"
ext.hibernate4Version = "4.2.16.Final"
ext.hibVal4Version = "4.3.2.Final"
ext.hsqldbVersion = "2.3.2"
ext.jackson1Version = "1.9.13"
ext.jackson2Version = "2.3.4"
ext.jasperReportsVersion = "5.5.1"
ext.jettyVersion = "9.1.5.v20140505"
ext.jodaVersion = "2.3"
ext.junitVersion = "4.11"
ext.openJpaVersion = "2.2.2"
ext.slf4jVersion = "1.7.9"
ext.tiles2Version = "2.2.2"
ext.tiles3Version = "3.0.5"
ext.tomcatVersion = "8.0.15"
ext.xstreamVersion = "1.4.7"
ext.gradleScriptDir = "${rootProject.projectDir}/gradle"
apply plugin: "propdeps"
@@ -57,45 +77,49 @@ configure(allprojects) { project ->
systemProperty("java.awt.headless", "true")
systemProperty("testGroups", project.properties.get("testGroups"))
scanForTestClasses = false
include '**/*Tests.*'
exclude '**/*Abstract*.*'
include(["**/*Tests.class", "**/*Test.class"])
// Since we set scanForTestClasses to false, we need to filter out inner
// classes with the "$" pattern; otherwise, using -Dtest.single=MyTests to
// run MyTests by itself will fail if MyTests contains any inner classes.
exclude(["**/Abstract*.class", '**/*$*'])
}
repositories {
maven { url "http://repo.spring.io/libs-release" }
maven { url "http://repo.spring.io/milestone" } // for AspectJ 1.8.0.M1
maven { url "https://repository.apache.org/content/repositories/releases" } // tomcat 8
// maven { url "https://repository.apache.org/content/repositories/snapshots" } // tomcat 8 snapshots
maven { url "https://maven.java.net/content/repositories/releases" } // javax.websocket, tyrus
maven { url "https://oss.sonatype.org/content/repositories/releases" } // javax.cache
maven { url "https://repo.spring.io/libs-release" }
}
dependencies {
testCompile("junit:junit:${junitVersion}")
testCompile("junit:junit:${junitVersion}") {
exclude group:'org.hamcrest', module:'hamcrest-core'
}
testCompile("org.mockito:mockito-core:1.9.5") {
exclude group:'org.hamcrest', module:'hamcrest-core'
}
testCompile("org.hamcrest:hamcrest-all:1.3")
testCompile("org.mockito:mockito-core:1.9.5")
}
ext.javadocLinks = [
"http://docs.oracle.com/javase/7/docs/api/",
"http://docs.oracle.com/javaee/6/api/",
"http://docs.oracle.com/cd/E13222_01/wls/docs90/javadocs/", // CommonJ
"http://pic.dhe.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.javadoc.doc/web/apidocs/",
"http://glassfish.java.net/nonav/docs/v3/api/",
"http://docs.jboss.org/jbossas/javadoc/4.0.5/connector/",
"http://docs.jboss.org/jbossas/javadoc/7.1.2.Final/",
"http://commons.apache.org/proper/commons-lang/javadocs/api-2.5/",
"http://commons.apache.org/proper/commons-codec/apidocs/",
"http://commons.apache.org/proper/commons-dbcp/apidocs/",
"http://portals.apache.org/pluto/portlet-2.0-apidocs/",
"http://tiles.apache.org/framework/apidocs/",
"https://docs.oracle.com/javase/7/docs/api/",
"https://docs.oracle.com/javaee/7/api/",
"https://docs.oracle.com/cd/E13222_01/wls/docs90/javadocs/", // CommonJ
"https://pic.dhe.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.javadoc.doc/web/apidocs/",
"https://glassfish.java.net/nonav/docs/v3/api/",
"https://docs.jboss.org/jbossas/javadoc/4.0.5/connector/",
"https://docs.jboss.org/jbossas/javadoc/7.1.2.Final/",
"https://commons.apache.org/proper/commons-lang/javadocs/api-2.5/",
"https://commons.apache.org/proper/commons-codec/apidocs/",
"https://commons.apache.org/proper/commons-dbcp/apidocs/",
"https://portals.apache.org/pluto/portlet-2.0-apidocs/",
"https://tiles.apache.org/tiles-request/apidocs/",
"https://tiles.apache.org/framework/apidocs/",
"http://aopalliance.sourceforge.net/doc/",
"http://www.eclipse.org/aspectj/doc/released/aspectj5rt-api/",
"http://ehcache.org/apidocs/",
"http://quartz-scheduler.org/api/2.1.7/",
"http://jackson.codehaus.org/1.9.4/javadoc/",
"http://fasterxml.github.com/jackson-core/javadoc/2.2.0/",
"http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs"
"https://www.eclipse.org/aspectj/doc/released/aspectj5rt-api/",
"https://www.ehcache.org/apidocs/2.6.9/",
"https://www.quartz-scheduler.org/api/2.2.2/",
"https://jackson.codehaus.org/1.9.4/javadoc/",
"https://fasterxml.github.io/jackson-core/javadoc/2.3.0/",
"https://fasterxml.github.io/jackson-databind/javadoc/2.3.0/",
"https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs"
] as String[]
}
@@ -132,10 +156,10 @@ configure(subprojects - project(":spring-build-src")) { subproject ->
logging.captureStandardOutput LogLevel.INFO // suppress "## warnings" message
}
task sourcesJar(type: Jar, dependsOn:classes) {
classifier = "sources"
from sourceSets.main.allJava.srcDirs
include "**/*.java", "**/*.aj"
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
// don't include or exclude anything explicitly by default. See SPR-12085.
}
task javadocJar(type: Jar) {
@@ -164,12 +188,12 @@ project("spring-build-src") {
project("spring-core") {
description = "Spring Core"
// As of Spring 4.0, spring-core includes asm 4.2 and repackages cglib 3.0, inlining
// both into the spring-core jar. cglib 3.0 itself depends on asm 4, and is therefore
// As of Spring 4.0.3, spring-core includes asm 5.0 and repackages cglib 3.1, inlining
// both into the spring-core jar. cglib 3.1 itself depends on asm 4+, and is therefore
// further transformed by the JarJar task to depend on org.springframework.asm; this
// avoids including two different copies of asm unnecessarily.
def cglibVersion = "3.0"
def objenesisVersion = "2.0"
def cglibVersion = "3.1"
def objenesisVersion = "2.1"
configurations {
jarjar
@@ -225,11 +249,11 @@ project("spring-core") {
jarjar("com.googlecode.jarjar:jarjar:1.3")
compile(files(cglibRepackJar))
compile("commons-logging:commons-logging:1.1.1")
compile("commons-logging:commons-logging:1.1.3")
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
optional("net.sf.jopt-simple:jopt-simple:4.4")
optional("net.sf.jopt-simple:jopt-simple:4.6")
optional("log4j:log4j:1.2.17")
testCompile("xmlunit:xmlunit:1.3")
testCompile("xmlunit:xmlunit:1.5")
testCompile("org.codehaus.woodstox:wstx-asl:3.2.7") {
exclude group: "stax", module: "stax-api"
}
@@ -261,14 +285,14 @@ project("spring-beans") {
dependencies {
compile(project(":spring-core"))
compile(files(project(":spring-core").cglibRepackJar))
provided("javax.el:javax.el-api:2.2.4")
provided("javax.inject:javax.inject:1")
optional("javax.inject:javax.inject:1")
optional("javax.el:javax.el-api:2.2.5")
testCompile("log4j:log4j:1.2.17")
}
}
project('spring-beans-groovy') {
description 'Groovy Bean Definitions'
project("spring-beans-groovy") {
description "Groovy Bean Definitions"
merge.into = project(":spring-beans")
apply plugin: "groovy"
@@ -282,7 +306,7 @@ project('spring-beans-groovy') {
sourceSets {
main {
groovy {
srcDir 'src/main/java'
srcDir "src/main/java"
}
}
}
@@ -297,14 +321,14 @@ project("spring-aop") {
description = "Spring AOP"
dependencies {
compile(project(":spring-beans"))
compile(project(":spring-core"))
compile(files(project(":spring-core").cglibRepackJar))
compile(files(project(":spring-core").objenesisRepackJar))
compile(project(":spring-beans"))
compile("aopalliance:aopalliance:1.0")
optional("com.jamonapi:jamon:2.4")
optional("commons-pool:commons-pool:1.5.3")
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
optional("commons-pool:commons-pool:1.6")
optional("com.jamonapi:jamon:2.4")
}
}
@@ -343,28 +367,26 @@ project("spring-context") {
apply plugin: "groovy"
dependencies {
optional(project(":spring-instrument"))
compile(project(":spring-aop"))
compile(project(":spring-beans"))
compile(project(":spring-expression"))
compile(project(":spring-core"))
compile(files(project(":spring-core").cglibRepackJar))
optional("javax.ejb:ejb-api:3.0")
optional(project(":spring-instrument"))
optional("javax.inject:javax.inject:1")
optional("javax.ejb:ejb-api:3.0")
optional("javax.enterprise.concurrent:javax.enterprise.concurrent-api:1.0")
optional("org.apache.geronimo.specs:geronimo-jms_1.1_spec:1.1")
optional("org.eclipse.persistence:javax.persistence:2.0.0")
optional("joda-time:joda-time:2.2")
optional("org.beanshell:bsh:2.0b4")
optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
optional("org.jruby:jruby:1.7.2")
optional("org.slf4j:slf4j-api:${slf4jVersion}")
optional("javax.validation:validation-api:1.0.0.GA")
optional("org.hibernate:hibernate-validator:4.3.0.Final")
optional("org.hibernate:hibernate-validator:${hibVal4Version}")
optional("joda-time:joda-time:${jodaVersion}")
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
optional("org.apache.geronimo.specs:geronimo-jta_1.1_spec:1.1")
testCompile("commons-dbcp:commons-dbcp:1.2.2")
optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
optional("org.beanshell:bsh:2.0b4")
optional("org.jruby:jruby:1.7.17")
testCompile("javax.inject:javax.inject-tck:1")
testCompile("commons-dbcp:commons-dbcp:1.4")
testCompile("org.slf4j:slf4j-api:${slf4jVersion}")
}
// pick up RmiInvocationWrapperRTD.xml in src/main
@@ -382,19 +404,19 @@ project("spring-messaging") {
compile(project(":spring-beans"))
compile(project(":spring-core"))
compile(project(":spring-context"))
optional("com.fasterxml.jackson.core:jackson-databind:2.2.2")
optional("org.projectreactor:reactor-core:1.0.0.RELEASE")
optional("org.projectreactor:reactor-tcp:1.0.0.RELEASE")
optional("org.projectreactor:reactor-core:1.1.5.RELEASE")
optional("org.projectreactor:reactor-net:1.1.5.RELEASE")
optional("org.projectreactor:reactor-tcp:1.0.1.RELEASE")
optional("org.eclipse.jetty.websocket:websocket-server:${jettyVersion}") {
exclude group: "javax.servlet", module: "javax.servlet-api"
}
optional("org.eclipse.jetty.websocket:websocket-client:${jettyVersion}")
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
testCompile(project(":spring-test"))
testCompile("com.thoughtworks.xstream:xstream:1.4.4")
testCompile("commons-dbcp:commons-dbcp:1.2.2")
testCompile("javax.inject:javax.inject-tck:1")
testCompile("javax.servlet:javax.servlet-api:3.1.0")
testCompile("log4j:log4j:1.2.17")
testCompile("javax.validation:validation-api:1.0.0.GA")
testCompile("com.thoughtworks.xstream:xstream:${xstreamVersion}")
testCompile("org.apache.activemq:activemq-broker:5.8.0")
testCompile("org.apache.activemq:activemq-kahadb-store:5.8.0") {
exclude group: "org.springframework", module: "spring-context"
@@ -403,8 +425,11 @@ project("spring-messaging") {
testCompile("org.eclipse.jetty:jetty-webapp:${jettyVersion}") {
exclude group: "javax.servlet", module: "javax.servlet-api"
}
testCompile("org.apache.tomcat.embed:tomcat-embed-core:8.0.0-RC5")
testCompile("org.apache.tomcat.embed:tomcat-embed-logging-juli:8.0.0-RC5")
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
testCompile("org.apache.tomcat.embed:tomcat-embed-websocket:${tomcatVersion}")
testCompile("org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}")
testCompile("commons-dbcp:commons-dbcp:1.4")
testCompile("log4j:log4j:1.2.17")
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
}
}
@@ -413,17 +438,17 @@ project("spring-tx") {
description = "Spring Transaction"
dependencies {
optional(project(":spring-context")) // for JCA, @EnableTransactionManagement
optional(project(":spring-aop"))
compile(project(":spring-beans"))
compile(project(":spring-core"))
compile("aopalliance:aopalliance:1.0")
provided("com.ibm.websphere:uow:6.0.2.17")
optional("javax.resource:connector-api:1.5")
optional(project(":spring-aop"))
optional(project(":spring-context")) // for JCA, @EnableTransactionManagement
optional("aopalliance:aopalliance:1.0")
optional("javax.transaction:javax.transaction-api:1.2")
optional("javax.resource:connector-api:1.5")
optional("javax.ejb:ejb-api:3.0")
testCompile("org.eclipse.persistence:javax.persistence:2.0.0")
optional("com.ibm.websphere:uow:6.0.2.17")
testCompile("org.aspectj:aspectjweaver:${aspectjVersion}")
testCompile("org.eclipse.persistence:javax.persistence:2.0.0")
}
}
@@ -431,14 +456,9 @@ project("spring-oxm") {
description = "Spring Object/XML Marshalling"
apply from: "oxm.gradle"
// The following is a work-around until the Gradle build uses
// Ant 1.9.x by default. This is necessary to avoid the genCastor
// "Class not found: javac1.8" issue with Ant versions prior to 1.9.x
ant.properties["build.compiler"] = "javac1.7"
compileTestJava {
// necessary to avoid java.lang.VerifyError on jibx compilation
// see http://jira.codehaus.org/browse/JIBX-465
// see https://jira.codehaus.org/browse/JIBX-465
sourceCompatibility=1.6
targetCompatibility=1.6
}
@@ -446,14 +466,24 @@ project("spring-oxm") {
dependencies {
compile(project(":spring-beans"))
compile(project(":spring-core"))
testCompile(project(":spring-context"))
optional("com.thoughtworks.xstream:xstream:1.4.4")
optional("org.codehaus.castor:castor-xml:1.3.3") {
exclude group: 'stax', module: 'stax-api'
exclude group: "org.springframework", module: "spring-context"
}
optional("org.apache.xmlbeans:xmlbeans:2.6.0") {
exclude group: 'stax', module: 'stax-api'
}
optional("com.thoughtworks.xstream:xstream:${xstreamVersion}") {
exclude group: 'xpp3', module: 'xpp3_min'
exclude group: 'xmlpull', module: 'xmlpull'
}
optional("org.jibx:jibx-run:1.2.5")
optional("org.apache.xmlbeans:xmlbeans:2.6.0")
optional("org.codehaus.castor:castor-xml:1.3.2")
testCompile("org.codehaus.jettison:jettison:1.0.1")
testCompile("xmlunit:xmlunit:1.3")
testCompile("xmlpull:xmlpull:1.1.3.4a")
testCompile(project(":spring-context"))
testCompile("xmlunit:xmlunit:1.5")
testCompile("xpp3:xpp3:1.1.3.4.O")
testCompile("org.codehaus.jettison:jettison:1.0.1") {
exclude group: 'stax', module: 'stax-api'
}
testCompile(files(genCastor.classesDir).builtBy(genCastor))
testCompile(files(genJaxb.classesDir).builtBy(genJaxb))
testCompile(files(genXmlbeans.classesDir).builtBy(genXmlbeans))
@@ -469,13 +499,13 @@ project("spring-jms") {
compile(project(":spring-aop"))
compile(project(":spring-context"))
compile(project(":spring-tx"))
provided("javax.jms:jms-api:1.1-rev-1")
optional(project(":spring-oxm"))
compile("aopalliance:aopalliance:1.0")
provided("org.apache.geronimo.specs:geronimo-jms_1.1_spec:1.1")
optional("org.apache.geronimo.specs:geronimo-jta_1.1_spec:1.1")
optional("aopalliance:aopalliance:1.0")
optional("javax.transaction:javax.transaction-api:1.2")
optional("javax.resource:connector-api:1.5")
optional("org.codehaus.jackson:jackson-mapper-asl:1.9.12")
optional("com.fasterxml.jackson.core:jackson-databind:2.2.2")
optional("org.codehaus.jackson:jackson-mapper-asl:${jackson1Version}")
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
}
}
@@ -483,16 +513,16 @@ project("spring-jdbc") {
description = "Spring JDBC"
dependencies {
compile(project(":spring-core"))
compile(project(":spring-beans"))
optional(project(":spring-context")) // for JndiDataSourceLookup
compile(project(":spring-core"))
compile(project(":spring-tx"))
optional("c3p0:c3p0:0.9.1.2")
optional(project(":spring-context")) // for JndiDataSourceLookup
optional("javax.transaction:javax.transaction-api:1.2")
optional("com.mchange:c3p0:0.9.2.1")
optional("org.hsqldb:hsqldb:${hsqldbVersion}")
optional("com.h2database:h2:1.0.71")
optional("org.apache.derby:derby:10.5.3.0_1")
optional("org.apache.derby:derbyclient:10.5.3.0_1")
optional("org.apache.geronimo.specs:geronimo-jta_1.1_spec:1.1")
optional("com.h2database:h2:1.3.176")
optional("org.apache.derby:derby:10.10.2.0")
optional("org.apache.derby:derbyclient:10.10.2.0")
}
}
@@ -503,25 +533,28 @@ project("spring-context-support") {
compile(project(":spring-core"))
compile(project(":spring-beans"))
compile(project(":spring-context"))
optional(project(":spring-jdbc")) // for Quartz support
optional(project(":spring-tx")) // for Quartz support
optional("javax.mail:mail:1.4.7")
optional("javax.cache:cache-api:1.0.0-PFD")
optional("net.sf.ehcache:ehcache-core:2.6.5")
optional(project(":spring-jdbc")) // for Quartz support
optional(project(":spring-tx")) // for Quartz support
optional("javax.mail:javax.mail-api:1.4.7")
optional("javax.cache:cache-api:1.0.0")
optional("com.google.guava:guava:17.0")
optional("net.sf.ehcache:ehcache-core:2.6.7")
optional("org.quartz-scheduler:quartz:1.8.6") {
exclude group: "org.slf4j", module: "slf4j-log4j12"
}
optional("org.codehaus.fabric3.api:commonj:1.1.0")
optional("org.apache.velocity:velocity:1.7")
optional("org.freemarker:freemarker:2.3.19")
optional("org.freemarker:freemarker:2.3.20")
optional("com.lowagie:itext:2.1.7")
optional("net.sf.jasperreports:jasperreports:5.1.0")
optional("org.slf4j:slf4j-api:${slf4jVersion}")
provided("javax.activation:activation:1.1")
testCompile("org.apache.poi:poi:3.9")
testCompile("commons-beanutils:commons-beanutils:1.8.0") // for Velocity/JasperReports
testCompile("commons-digester:commons-digester:1.8.1") // for Velocity/JasperReports
optional("net.sf.jasperreports:jasperreports:$jasperReportsVersion") {
exclude group: "xml-apis", module: "xml-apis"
}
testCompile("org.apache.poi:poi:3.10.1")
testCompile("commons-beanutils:commons-beanutils:1.8.0") // for Velocity/JasperReports
testCompile("commons-digester:commons-digester:1.8.1") // for Velocity/JasperReports
testCompile("org.hsqldb:hsqldb:${hsqldbVersion}")
testCompile("org.slf4j:slf4j-api:${slf4jVersion}")
testRuntime("com.sun.mail:javax.mail:1.4.7")
}
// pick up **/*.types files in src/main
@@ -532,26 +565,24 @@ project("spring-web") {
description = "Spring Web"
dependencies {
compile(project(":spring-core"))
compile(project(":spring-beans")) // for MultiPartFilter
compile(project(":spring-aop")) // for JaxWsPortProxyFactoryBean
compile(project(":spring-aop")) // for JaxWsPortProxyFactoryBean
compile(project(":spring-beans")) // for MultipartFilter
compile(project(":spring-context"))
optional(project(":spring-oxm")) // for MarshallingHttpMessageConverter
compile("aopalliance:aopalliance:1.0")
provided("javax.el:javax.el-api:2.2.4")
provided("javax.faces:javax.faces-api:2.2")
provided("javax.portlet:portlet-api:2.0")
compile(project(":spring-core"))
provided("javax.servlet:javax.servlet-api:3.0.1")
provided("javax.servlet.jsp:jsp-api:2.1")
provided("javax.activation:activation:1.1")
optional(project(":spring-oxm")) // for MarshallingHttpMessageConverter
optional("javax.servlet.jsp:javax.servlet.jsp-api:2.2.1")
optional("javax.portlet:portlet-api:2.0")
optional("javax.el:javax.el-api:2.2.5")
optional("javax.faces:javax.faces-api:2.2")
optional("aopalliance:aopalliance:1.0")
optional("com.caucho:hessian:4.0.7")
optional("commons-fileupload:commons-fileupload:1.3.1")
optional("org.apache.httpcomponents:httpclient:4.3.6")
optional("org.apache.httpcomponents:httpasyncclient:4.0.2")
optional("org.codehaus.jackson:jackson-mapper-asl:${jackson1Version}")
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
optional("rome:rome:1.0")
optional("commons-fileupload:commons-fileupload:1.3")
optional("org.apache.httpcomponents:httpclient:4.3.1")
optional("org.apache.httpcomponents:httpasyncclient:4.0")
optional("org.codehaus.jackson:jackson-mapper-asl:1.9.12")
optional("com.fasterxml.jackson.core:jackson-databind:2.2.2")
optional("taglibs:standard:1.1.2")
optional("org.eclipse.jetty:jetty-servlet:${jettyVersion}") {
exclude group: "javax.servlet", module: "javax.servlet-api"
}
@@ -560,9 +591,11 @@ project("spring-web") {
}
optional("log4j:log4j:1.2.17")
testCompile(project(":spring-context-support")) // for JafMediaTypeFactory
testCompile("xmlunit:xmlunit:1.3")
testCompile("xmlunit:xmlunit:1.5")
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
testCompile("log4j:log4j:1.2.17")
testCompile("org.apache.taglibs:taglibs-standard-jstlel:1.2.1") {
exclude group: "org.apache.taglibs", module: "taglibs-standard-spec"
}
}
// pick up ContextLoader.properties in src/main
@@ -580,7 +613,7 @@ project("spring-websocket") {
optional(project(":spring-webmvc"))
optional("javax.servlet:javax.servlet-api:3.1.0")
optional("javax.websocket:javax.websocket-api:1.0")
optional("org.apache.tomcat:tomcat-websocket:8.0.0-RC5") {
optional("org.apache.tomcat:tomcat-websocket:${tomcatVersion}") {
exclude group: "org.apache.tomcat", module: "tomcat-websocket-api"
exclude group: "org.apache.tomcat", module: "tomcat-servlet-api"
}
@@ -593,13 +626,22 @@ project("spring-websocket") {
exclude group: "javax.servlet", module: "javax.servlet"
}
optional("org.eclipse.jetty.websocket:websocket-client:${jettyVersion}")
optional("com.fasterxml.jackson.core:jackson-databind:2.2.2")
optional("org.codehaus.jackson:jackson-mapper-asl:1.9.12")
testCompile("org.apache.tomcat.embed:tomcat-embed-core:8.0.0-RC5")
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
optional("io.undertow:undertow-core:1.0.1.Final")
optional("io.undertow:undertow-servlet:1.0.1.Final") {
exclude group: "org.jboss.spec.javax.servlet", module: "jboss-servlet-api_3.1_spec"
exclude group: "org.jboss.spec.javax.annotation", module: "jboss-annotations-api_1.2_spec"
}
optional("io.undertow:undertow-websockets-jsr:1.0.1.Final") {
exclude group: "org.jboss.spec.javax.websocket", module: "jboss-websocket-api_1.0_spec"
}
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
testCompile("org.apache.tomcat.embed:tomcat-embed-websocket:${tomcatVersion}")
testCompile("org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}")
testCompile("org.projectreactor:reactor-core:1.1.4.RELEASE")
testCompile("org.projectreactor:reactor-net:1.1.4.RELEASE")
testCompile("log4j:log4j:1.2.17")
testCompile("org.projectreactor:reactor-core:1.0.0.RELEASE")
testCompile("org.projectreactor:reactor-tcp:1.0.0.RELEASE")
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
}
}
@@ -607,25 +649,39 @@ project("spring-orm") {
description = "Spring Object/Relational Mapping"
dependencies {
compile("aopalliance:aopalliance:1.0")
optional("org.eclipse.persistence:javax.persistence:2.0.0")
optional("org.eclipse.persistence:org.eclipse.persistence.core:2.4.0")
optional("org.eclipse.persistence:org.eclipse.persistence.jpa:2.4.0")
optional("org.hibernate:hibernate-core:3.6.9.Final")
optional("org.hibernate:hibernate-entitymanager:3.6.9.Final")
optional("org.apache.openjpa:openjpa:2.2.1")
optional("javax.jdo:jdo-api:3.0")
provided("javax.servlet:javax.servlet-api:3.0.1")
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
testCompile("commons-dbcp:commons-dbcp:1.2.2")
testCompile("org.hsqldb:hsqldb:${hsqldbVersion}")
compile(project(":spring-core"))
compile(project(":spring-beans"))
compile(project(":spring-core"))
compile(project(":spring-jdbc"))
compile(project(":spring-tx"))
optional(project(":spring-aop"))
optional(project(":spring-context"))
compile(project(":spring-tx"))
compile(project(":spring-jdbc"))
optional(project(":spring-web"))
optional("aopalliance:aopalliance:1.0")
optional("org.eclipse.persistence:javax.persistence:2.0.5")
optional("org.eclipse.persistence:org.eclipse.persistence.core:${eclipseLinkVersion}")
optional("org.eclipse.persistence:org.eclipse.persistence.jpa:${eclipseLinkVersion}") {
exclude group: 'org.eclipse.persistence', module: 'javax.persistence'
}
optional("org.hibernate:hibernate-core:${hibernate3Version}") {
exclude group: 'org.hibernate.javax.persistence', module: 'hibernate-jpa-2.0-api'
exclude group: 'javax.transaction', module: 'jta'
}
optional("org.hibernate:hibernate-entitymanager:${hibernate3Version}") {
exclude group: 'org.hibernate.javax.persistence', module: 'hibernate-jpa-2.0-api'
}
optional("org.apache.openjpa:openjpa:${openJpaVersion}") {
exclude group: 'junit', module: 'junit'
exclude group: 'org.apache.geronimo.specs', module: 'geronimo-jpa_2.0_spec'
exclude group: 'org.apache.geronimo.specs', module: 'geronimo-jta_1.1_spec'
exclude group: 'org.apache.geronimo.specs', module: 'geronimo-jms_1.1_spec'
}
optional("javax.jdo:jdo-api:3.0.1") {
exclude group: 'javax.transaction', module: 'transaction-api'
}
optional("javax.servlet:javax.servlet-api:3.0.1")
testCompile("commons-dbcp:commons-dbcp:1.4")
testCompile("org.hsqldb:hsqldb:${hsqldbVersion}")
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
}
}
@@ -634,12 +690,13 @@ project("spring-orm-hibernate4") {
merge.into = project(":spring-orm")
dependencies {
provided(project(":spring-tx"))
provided(project(":spring-jdbc"))
optional("org.hibernate:hibernate-core:4.2.2.Final")
optional("org.hibernate:hibernate-entitymanager:4.2.2.Final")
provided(project(":spring-tx"))
optional(project(":spring-web"))
optional("org.hibernate:hibernate-core:${hibernate4Version}")
optional("org.hibernate:hibernate-entitymanager:${hibernate4Version}")
optional("javax.servlet:javax.servlet-api:3.0.1")
optional("aopalliance:aopalliance:1.0")
}
}
@@ -647,37 +704,50 @@ project("spring-webmvc") {
description = "Spring Web MVC"
dependencies {
compile(project(":spring-beans"))
compile(project(":spring-context"))
compile(project(":spring-core"))
compile(files(project(":spring-core").objenesisRepackJar))
compile(project(":spring-expression"))
compile(project(":spring-beans"))
compile(project(":spring-web"))
compile(project(":spring-context"))
optional(project(":spring-context-support")) // for Velocity support
optional(project(":spring-oxm")) // for MarshallingView
optional("org.apache.tiles:tiles-api:2.1.2")
optional("org.apache.tiles:tiles-core:2.1.2")
optional("org.apache.tiles:tiles-jsp:2.1.2")
optional("org.apache.tiles:tiles-servlet:2.1.2")
optional("net.sourceforge.jexcelapi:jxl:2.6.3")
optional("org.apache.poi:poi:3.9")
optional("com.lowagie:itext:2.1.7")
optional("net.sf.jasperreports:jasperreports:5.1.0") {
exclude group: "xml-apis", module: "xml-apis"
}
optional("rome:rome:1.0")
provided("javax.servlet:javax.servlet-api:3.0.1")
optional(project(":spring-context-support")) // for Velocity support
optional(project(":spring-oxm")) // for MarshallingView
optional("javax.servlet.jsp:javax.servlet.jsp-api:2.2.1")
optional("javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:1.2.1")
optional("net.sourceforge.jexcelapi:jxl:2.6.12")
optional("org.apache.poi:poi:3.10.1")
optional("org.apache.velocity:velocity:1.7")
optional("velocity-tools:velocity-tools-view:1.4")
optional("org.freemarker:freemarker:2.3.19")
optional("org.codehaus.jackson:jackson-mapper-asl:1.9.12")
optional("com.fasterxml.jackson.core:jackson-databind:2.2.2")
provided("javax.servlet:jstl:1.2")
provided("javax.servlet:javax.servlet-api:3.0.1")
provided("javax.servlet.jsp:jsp-api:2.1")
optional("org.freemarker:freemarker:2.3.20")
optional("com.lowagie:itext:2.1.7")
optional("net.sf.jasperreports:jasperreports:$jasperReportsVersion") {
exclude group: "xml-apis", module: "xml-apis"
}
optional("org.codehaus.jackson:jackson-mapper-asl:${jackson1Version}")
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
optional("rome:rome:1.0")
optional("org.apache.tiles:tiles-api:${tiles2Version}")
optional("org.apache.tiles:tiles-core:${tiles2Version}") {
exclude group: "org.slf4j", module: "jcl-over-slf4j"
}
optional("org.apache.tiles:tiles-servlet:${tiles2Version}") {
exclude group: "org.slf4j", module: "jcl-over-slf4j"
}
optional("org.apache.tiles:tiles-jsp:${tiles2Version}") {
exclude group: "org.slf4j", module: "jcl-over-slf4j"
}
optional("org.apache.tiles:tiles-el:${tiles2Version}") {
exclude group: "org.slf4j", module: "jcl-over-slf4j"
}
optional("org.apache.tiles:tiles-extras:${tiles2Version}") {
exclude group: "org.slf4j", module: "jcl-over-slf4j"
exclude group: "org.apache.velocity", module: "velocity-tools"
exclude group: "org.springframework", module: "spring-web"
}
testCompile(project(":spring-aop"))
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
testCompile("rhino:js:1.7R1")
testCompile("xmlunit:xmlunit:1.3")
testCompile("xmlunit:xmlunit:1.5")
testCompile("dom4j:dom4j:1.6.1") {
exclude group: "xml-apis", module: "xml-apis"
}
@@ -693,11 +763,12 @@ project("spring-webmvc") {
exclude group: "javax.servlet", module: "javax.servlet"
}
testCompile("javax.validation:validation-api:1.0.0.GA")
testCompile("commons-fileupload:commons-fileupload:1.2")
testCompile("org.hibernate:hibernate-validator:${hibVal4Version}")
testCompile("org.apache.httpcomponents:httpclient:4.3.6")
testCompile("commons-fileupload:commons-fileupload:1.3.1")
testCompile("commons-io:commons-io:1.3")
testCompile("org.hibernate:hibernate-validator:4.3.0.Final")
testCompile("org.apache.httpcomponents:httpclient:4.3.1")
testCompile("joda-time:joda-time:2.2")
testCompile("joda-time:joda-time:${jodaVersion}")
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
}
// pick up DispatcherServlet.properties in src/main
@@ -711,28 +782,27 @@ project("spring-webmvc-tiles3") {
dependencies {
provided(project(":spring-context"))
provided(project(":spring-web"))
provided("javax.el:javax.el-api:2.2.4")
provided("javax.servlet:jstl:1.2")
provided("javax.servlet.jsp:jsp-api:2.1")
optional("org.apache.tiles:tiles-request-api:1.0.1")
optional("org.apache.tiles:tiles-api:3.0.1")
optional("org.apache.tiles:tiles-core:3.0.1") {
provided("javax.servlet:javax.servlet-api:3.0.1")
optional("javax.servlet.jsp:javax.servlet.jsp-api:2.2.1")
optional("javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:1.2.1")
optional("javax.el:javax.el-api:2.2.5")
optional("org.apache.tiles:tiles-api:${tiles3Version}")
optional("org.apache.tiles:tiles-core:${tiles3Version}") {
exclude group: "org.slf4j", module: "jcl-over-slf4j"
}
optional("org.apache.tiles:tiles-servlet:3.0.1") {
optional("org.apache.tiles:tiles-servlet:${tiles3Version}") {
exclude group: "org.slf4j", module: "jcl-over-slf4j"
}
optional("org.apache.tiles:tiles-jsp:3.0.1") {
optional("org.apache.tiles:tiles-jsp:${tiles3Version}") {
exclude group: "org.slf4j", module: "jcl-over-slf4j"
}
optional("org.apache.tiles:tiles-extras:3.0.1") {
optional("org.apache.tiles:tiles-el:${tiles3Version}") {
exclude group: "org.slf4j", module: "jcl-over-slf4j"
}
optional("org.apache.tiles:tiles-extras:${tiles3Version}") {
exclude group: "org.slf4j", module: "jcl-over-slf4j"
exclude group: "org.springframework", module: "spring-web"
}
optional("org.apache.tiles:tiles-el:3.0.1") {
exclude group: "org.slf4j", module: "jcl-over-slf4j"
}
provided("javax.servlet:javax.servlet-api:3.0.1")
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
}
}
@@ -741,14 +811,14 @@ project("spring-webmvc-portlet") {
description = "Spring Web Portlet"
dependencies {
provided("javax.servlet:javax.servlet-api:3.0.1")
provided("javax.portlet:portlet-api:2.0")
compile(project(":spring-core"))
compile(project(":spring-beans"))
compile(project(":spring-context"))
compile(project(":spring-core"))
compile(project(":spring-web"))
compile(project(":spring-webmvc"))
optional("commons-fileupload:commons-fileupload:1.2")
provided("javax.servlet:javax.servlet-api:3.0.1")
provided("javax.portlet:portlet-api:2.0")
optional("commons-fileupload:commons-fileupload:1.3.1")
}
// pick up DispatcherPortlet.properties in src/main
@@ -769,59 +839,70 @@ project("spring-test") {
optional(project(":spring-webmvc"))
optional(project(":spring-webmvc-portlet"))
optional("junit:junit:${junitVersion}")
optional("org.testng:testng:6.8.5")
optional("org.testng:testng:6.8.8")
optional("javax.inject:javax.inject:1")
optional("javax.servlet:javax.servlet-api:3.0.1")
optional("javax.servlet.jsp:jsp-api:2.1")
optional("javax.servlet.jsp:javax.servlet.jsp-api:2.2.1")
optional("javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:1.2.1")
optional("org.apache.taglibs:taglibs-standard-jstlel:1.2.1") {
exclude group: "org.apache.taglibs", module: "taglibs-standard-spec"
}
optional("javax.portlet:portlet-api:2.0")
optional("javax.el:javax.el-api:2.2.5")
optional("org.eclipse.persistence:javax.persistence:2.0.0")
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
provided("javax.inject:javax.inject:1")
provided("javax.activation:activation:1.1")
provided("javax.servlet:jstl:1.2")
optional("org.hamcrest:hamcrest-core:1.3")
optional("com.jayway.jsonpath:json-path:0.9.0")
optional("xmlunit:xmlunit:1.3")
optional("com.jayway.jsonpath:json-path:0.9.1")
optional("xmlunit:xmlunit:1.5")
testCompile(project(":spring-context-support"))
testCompile(project(":spring-oxm"))
testCompile(project(":spring-webmvc-tiles3"))
testCompile("org.hibernate:hibernate-core:3.6.9.Final")
testCompile "org.slf4j:slf4j-jcl:${slf4jVersion}"
testCompile("org.hsqldb:hsqldb:${hsqldbVersion}")
testCompile("org.hibernate:hibernate-validator:4.3.0.Final")
testCompile("org.codehaus.jackson:jackson-mapper-asl:1.9.12")
testCompile("com.fasterxml.jackson.core:jackson-databind:2.2.2")
testCompile("com.thoughtworks.xstream:xstream:1.4.4")
testCompile("javax.mail:javax.mail-api:1.4.7")
testCompile("javax.ejb:ejb-api:3.0")
testCompile("org.hibernate:hibernate-core:${hibernate3Version}") {
exclude group: 'org.hibernate.javax.persistence', module: 'hibernate-jpa-2.0-api'
}
testCompile("org.hibernate:hibernate-entitymanager:${hibernate3Version}")
testCompile("org.hibernate:hibernate-validator:${hibVal4Version}")
testCompile("com.thoughtworks.xstream:xstream:${xstreamVersion}")
testCompile("org.codehaus.jackson:jackson-mapper-asl:${jackson1Version}")
testCompile("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
testCompile("rome:rome:1.0")
testCompile("javax.activation:activation:1.1")
testCompile("javax.mail:mail:1.4.7")
testCompile("org.apache.tiles:tiles-request-api:1.0.1")
testCompile("org.apache.tiles:tiles-api:3.0.1")
testCompile("org.apache.tiles:tiles-core:3.0.1") {
testCompile("org.apache.tiles:tiles-api:${tiles3Version}")
testCompile("org.apache.tiles:tiles-core:${tiles3Version}") {
exclude group: "org.slf4j", module: "jcl-over-slf4j"
}
testCompile("org.apache.tiles:tiles-servlet:3.0.1") {
testCompile("org.apache.tiles:tiles-servlet:${tiles3Version}") {
exclude group: "org.slf4j", module: "jcl-over-slf4j"
}
testCompile("org.hsqldb:hsqldb:${hsqldbVersion}")
testCompile "org.slf4j:slf4j-jcl:${slf4jVersion}"
}
task testNG(type: Test) {
description = 'Runs TestNG tests.'
useTestNG()
scanForTestClasses = false
include "**/testng/*.*"
exclude "**/FailingBeforeAndAfterMethodsTests.class"
// "TestCase" classes are run by other test classes, not the build.
exclude "**/*TestCase.class"
// Generate TestNG reports alongside JUnit reports.
getReports().getHtml().setEnabled(true)
include(["**/testng/**/*Tests.class", "**/testng/**/*Test.class"])
// Show STD_OUT & STD_ERR of the test JVM(s) on the console:
// testLogging.showStandardStreams = true
// forkEvery 1
}
test {
description = 'Runs JUnit tests.'
dependsOn testNG
useJUnit()
exclude "**/testng/*.*"
// "TestCase" classes are run by other test classes, not the build.
exclude(["**/*TestCase.class", "**/*TestSuite.class"])
exclude "**/testng/**/*.*"
}
task aggregateTestReports(type: TestReport) {
description = 'Aggregates JUnit and TestNG test reports.'
destinationDir = test.reports.html.destination
reportOn test, testNG
}
check.dependsOn aggregateTestReports
}
project("spring-aspects") {
@@ -829,21 +910,20 @@ project("spring-aspects") {
apply from: "aspects.gradle"
dependencies {
optional(project(":spring-beans")) // for @Configurable support
optional(project(":spring-aop")) // for @Async support
optional(project(":spring-context")) // for @Enable* support
compile(project(":spring-context-support")) // for JavaMail support
optional(project(":spring-tx")) // for JPA, @Transactional support
optional(project(":spring-orm")) // for JPA exception translation support
aspects(project(":spring-orm"))
provided("org.eclipse.persistence:javax.persistence:2.0.0")
testCompile("javax.mail:mail:1.4.7")
ajc("org.aspectj:aspectjtools:${aspectjVersion}")
rt("org.aspectj:aspectjrt:${aspectjVersion}")
compile("org.aspectj:aspectjweaver:${aspectjVersion}")
testCompile(project(":spring-core")) // for CodeStyleAspect
compile(project(":spring-beans")) // for "p" namespace visibility
provided("org.eclipse.persistence:javax.persistence:2.0.0")
optional(project(":spring-aop")) // for @Async support
optional(project(":spring-beans")) // for @Configurable support
optional(project(":spring-context")) // for @Enable* support
optional(project(":spring-context-support")) // for JavaMail support
optional(project(":spring-orm")) // for JPA exception translation support
optional(project(":spring-tx")) // for JPA, @Transactional support
testCompile(project(":spring-core")) // for CodeStyleAspect
testCompile(project(":spring-test"))
testCompile("javax.mail:javax.mail-api:1.4.7")
}
eclipse.project {
@@ -932,23 +1012,23 @@ configure(rootProject) {
configurations.archives.artifacts.clear()
dependencies { // for integration tests
testCompile(project(":spring-core"))
testCompile(project(":spring-beans"))
testCompile(project(":spring-aop"))
testCompile(project(":spring-expression"))
testCompile(project(":spring-beans"))
testCompile(project(":spring-context"))
testCompile(project(":spring-tx"))
testCompile(project(":spring-core"))
testCompile(project(":spring-expression"))
testCompile(project(":spring-jdbc"))
testCompile(project(":spring-orm"))
testCompile(project(":spring-test"))
testCompile(project(":spring-tx"))
testCompile(project(":spring-web"))
testCompile(project(":spring-webmvc-portlet"))
testCompile(project(":spring-orm"))
testCompile("org.hibernate:hibernate-core:4.2.2.Final")
testCompile("javax.servlet:javax.servlet-api:3.0.1")
testCompile("javax.portlet:portlet-api:2.0")
testCompile("javax.inject:javax.inject:1")
testCompile("javax.resource:connector-api:1.5")
testCompile("org.aspectj:aspectjweaver:${aspectjVersion}")
testCompile("org.hibernate:hibernate-core:${hibernate4Version}")
testCompile("org.hsqldb:hsqldb:${hsqldbVersion}")
}
@@ -980,7 +1060,7 @@ configure(rootProject) {
doFirst {
classpath = files(
// ensure servlet 3.x and Hibernate 4.x have precedence on the Javadoc
// ensure Servlet 3.x and Hibernate 4.x have precedence on the javadoc
// classpath over their respective 2.5 and 3.x variants
project(":spring-webmvc").sourceSets.main.compileClasspath.files.find { it =~ "servlet-api" },
rootProject.sourceSets.test.compileClasspath.files.find { it =~ "hibernate-core" },
@@ -996,7 +1076,7 @@ configure(rootProject) {
baseName = "spring-framework"
classifier = "docs"
description = "Builds -${classifier} archive containing api and reference " +
"for deployment at http://static.springframework.org/spring-framework/docs."
"for deployment at https://docs.spring.io/spring-framework/docs."
from("src/dist") {
include "changelog.txt"
@@ -1016,9 +1096,9 @@ configure(rootProject) {
baseName = "spring-framework"
classifier = "schema"
description = "Builds -${classifier} archive containing all " +
"XSDs for deployment at http://springframework.org/schema."
subprojects.each { subproject ->
"XSDs for deployment at https://springframework.org/schema."
duplicatesStrategy 'exclude'
moduleProjects.each { subproject ->
def Properties schemas = new Properties();
subproject.sourceSets.main.resources.find {
@@ -1064,7 +1144,7 @@ configure(rootProject) {
into "${baseDir}/schema"
}
subprojects.each { subproject ->
moduleProjects.each { subproject ->
into ("${baseDir}/libs") {
from subproject.jar
if (subproject.tasks.findByPath("sourcesJar")) {
@@ -1077,7 +1157,7 @@ configure(rootProject) {
}
}
// Create an distribution that contains all dependencies (required and optional).
// Create a distribution that contains all dependencies (required and optional).
// Not published by default; only for use when building from source.
task depsZip(type: Zip, dependsOn: distZip) { zipTask ->
group = "Distribution"
@@ -1117,7 +1197,7 @@ configure(rootProject) {
task wrapper(type: Wrapper) {
description = "Generates gradlew[.bat] scripts"
gradleVersion = "1.9"
gradleVersion = "1.12"
doLast() {
def gradleOpts = "-XX:MaxMetaspaceSize=1024m -Xmx1024m"
@@ -21,16 +21,13 @@ import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ProjectDependency;
import org.gradle.api.artifacts.maven.Conf2ScopeMapping
import org.gradle.api.plugins.MavenPlugin
import org.gradle.api.tasks.*
import org.gradle.plugins.ide.eclipse.EclipsePlugin
import org.gradle.plugins.ide.eclipse.model.EclipseClasspath;
import org.gradle.plugins.ide.idea.IdeaPlugin
import org.gradle.api.invocation.*
/**
* Gradle plugin that allows projects to merged together. Primarily developed to
* allow Spring to support multiple multiple incompatible versions of third-party
* allow Spring to support multiple incompatible versions of third-party
* dependencies (for example Hibernate v3 and v4).
* <p>
* The 'merge' extension should be used to define how projects are merged, for example:
@@ -76,13 +73,13 @@ class MergePlugin implements Plugin<Project> {
// Hook to perform the actual merge logic
project.afterEvaluate{
if(it.merge.into != null) {
if (it.merge.into != null) {
setup(it)
}
}
// Hook to build runtimeMerge dependencies
if(!attachedProjectsEvaluated) {
if (!attachedProjectsEvaluated) {
project.gradle.projectsEvaluated{
postProcessProjects(it)
}
@@ -102,7 +99,7 @@ class MergePlugin implements Plugin<Project> {
// invoking a task will invoke the task with the same name on 'into' project
["sourcesJar", "jar", "javadocJar", "javadoc", "install", "artifactoryPublish"].each {
def task = project.tasks.findByPath(it)
if(task) {
if (task) {
task.enabled = false
task.dependsOn(project.merge.into.tasks.findByPath(it))
}
@@ -120,7 +117,7 @@ class MergePlugin implements Plugin<Project> {
private void setupMaven(Project project) {
project.configurations.each { configuration ->
Conf2ScopeMapping mapping = project.conf2ScopeMappings.getMapping([configuration])
if(mapping.scope) {
if (mapping.scope) {
Configuration intoConfiguration = project.merge.into.configurations.create(
project.name + "-" + configuration.name)
configuration.excludeRules.each {
@@ -131,7 +128,7 @@ class MergePlugin implements Plugin<Project> {
configuration.dependencies.each {
def intoCompile = project.merge.into.configurations.getByName("compile")
// Protect against changing a compile scope dependency (SPR-10218)
if(!intoCompile.dependencies.contains(it)) {
if (!intoCompile.dependencies.contains(it)) {
intoConfiguration.dependencies.add(it)
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@ import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.ProjectDependency;
/**
* Gradle plugin that automatically updates testCompile dependencies to include
* the test source sets of project dependencies.
@@ -41,11 +40,10 @@ class TestSourceSetDependenciesPlugin implements Plugin<Project> {
}
}
private void collectProjectDependencies(Set<ProjectDependency> projectDependencies,
Project project) {
for(def configurationName in ["compile", "optional", "provided", "testCompile"]) {
private void collectProjectDependencies(Set<ProjectDependency> projectDependencies, Project project) {
for (def configurationName in ["compile", "optional", "provided", "testCompile"]) {
Configuration configuration = project.getConfigurations().findByName(configurationName)
if(configuration) {
if (configuration) {
configuration.dependencies.findAll { it instanceof ProjectDependency }.each {
projectDependencies.add(it)
collectProjectDependencies(projectDependencies, it.dependencyProject)
+1 -1
View File
@@ -1 +1 @@
version=4.0.0.RC2
version=4.0.10.BUILD-SNAPSHOT
+11
View File
@@ -47,6 +47,17 @@ eclipse.classpath.file.whenMerged { classpath ->
}
}
// Ensure project dependencies come after 3rd-party libs (SPR-11836)
// https://jira.spring.io/browse/SPR-11836
eclipse.classpath.file.whenMerged { classpath ->
classpath.entries.findAll { it instanceof ProjectDependency }.each {
// delete from original position
classpath.entries.remove(it)
// append to end of classpath
classpath.entries.add(it)
}
}
// Allow projects to be used as WPT modules
eclipse.project.natures "org.eclipse.wst.common.project.facet.core.nature"
+8 -8
View File
@@ -22,28 +22,28 @@ def customizePom(pom, gradleProject) {
generatedPom.project {
name = gradleProject.description
description = gradleProject.description
url = "https://github.com/SpringSource/spring-framework"
url = "https://github.com/spring-projects/spring-framework"
organization {
name = "SpringSource"
url = "http://springsource.org/spring-framework"
name = "Spring IO"
url = "https://projects.spring.io/spring-framework"
}
licenses {
license {
name "The Apache Software License, Version 2.0"
url "http://www.apache.org/licenses/LICENSE-2.0.txt"
url "https://www.apache.org/licenses/LICENSE-2.0.txt"
distribution "repo"
}
}
scm {
url = "https://github.com/SpringSource/spring-framework"
connection = "scm:git:git://github.com/SpringSource/spring-framework"
developerConnection = "scm:git:git://github.com/SpringSource/spring-framework"
url = "https://github.com/spring-projects/spring-framework"
connection = "scm:git:git://github.com/spring-projects/spring-framework"
developerConnection = "scm:git:git://github.com/spring-projects/spring-framework"
}
developers {
developer {
id = "jhoeller"
name = "Juergen Hoeller"
email = "jhoeller@vmware.com"
email = "jhoeller@gopivotal.com"
}
}
issueManagement {
Binary file not shown.
+2 -2
View File
@@ -1,6 +1,6 @@
#Wed Nov 20 13:14:38 PST 2013
#Wed Apr 30 13:06:57 CEST 2014
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=http\://services.gradle.org/distributions/gradle-1.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-1.12-bin.zip
+1 -1
View File
@@ -17,7 +17,7 @@ echo been tested against STS %STS_TEST_VERSION%), but at the minimum you will
echo need Eclipse + AJDT.
echo.
echo If you need to download and install STS, please do that now by
echo visiting http://spring.io/tools/sts/all
echo visiting https://spring.io/tools/sts/all
echo.
echo Otherwise, press enter and we'll begin.
+1 -1
View File
@@ -14,7 +14,7 @@ been tested against STS $STS_TEST_VERSION), but at the minimum you will
need Eclipse + AJDT.
If you need to download and install STS, please do that now by
visiting http://spring.io/tools/sts/all
visiting https://spring.io/tools/sts/all
Otherwise, press enter and we'll begin.
EOM
+3 -2
View File
@@ -12,10 +12,11 @@ _Within your locally cloned spring-framework working directory:_
## Known issues
1. `spring-aspects` does not compile out of the box due to references to aspect types unknown to IDEA.
1. Those steps don't work currently for Intellij IDEA 13+
2. `spring-aspects` does not compile out of the box due to references to aspect types unknown to IDEA.
See http://youtrack.jetbrains.com/issue/IDEA-64446 for details. In the meantime, the 'spring-aspects'
module has been excluded from the overall project to avoid compilation errors.
2. While all JUnit tests pass from the command line with Gradle, many will fail when run from IDEA.
3. While all JUnit tests pass from the command line with Gradle, many will fail when run from IDEA.
Resolving this is a work in progress. If attempting to run all JUnit tests from within IDEA, you will
likely need to set the following VM options to avoid out of memory errors:
-XX:MaxPermSize=2048m -Xmx2048m -XX:MaxHeapSize=2048m
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,9 +19,9 @@ package org.springframework.aop;
import java.lang.reflect.Method;
/**
* A specialized type of MethodMatcher that takes into account introductions when
* matching methods. If there are no introductions on the target class, a method
* matcher may be able to optimize matching more effectively for example.
* A specialized type of {@link MethodMatcher} that takes into account introductions
* when matching methods. If there are no introductions on the target class,
* a method matcher may be able to optimize matching more effectively for example.
*
* @author Adrian Colyer
* @since 2.0
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -240,7 +240,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
setArgumentNamesFromStringArray(tokens);
}
public void setArgumentNamesFromStringArray(String[] args) {
public void setArgumentNamesFromStringArray(String... args) {
this.argumentNames = new String[args.length];
for (int i = 0; i < args.length; i++) {
this.argumentNames[i] = StringUtils.trimWhitespace(args[i]);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,7 +29,6 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.patterns.NamePattern;
import org.aspectj.weaver.reflect.ReflectionWorld;
import org.aspectj.weaver.reflect.ReflectionWorld.ReflectionWorldException;
import org.aspectj.weaver.reflect.ShadowMatchImpl;
import org.aspectj.weaver.tools.ContextBasedMatcher;
@@ -42,6 +41,7 @@ import org.aspectj.weaver.tools.PointcutParameter;
import org.aspectj.weaver.tools.PointcutParser;
import org.aspectj.weaver.tools.PointcutPrimitive;
import org.aspectj.weaver.tools.ShadowMatch;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.IntroductionAwareMethodMatcher;
import org.springframework.aop.MethodMatcher;
@@ -55,6 +55,7 @@ import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
@@ -106,6 +107,8 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
private BeanFactory beanFactory;
private transient ClassLoader pointcutClassLoader;
private transient PointcutExpression pointcutExpression;
private transient Map<Method, ShadowMatch> shadowMatchCache = new ConcurrentHashMap<Method, ShadowMatch>(32);
@@ -144,14 +147,14 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
/**
* Set the parameter names for the pointcut.
*/
public void setParameterNames(String[] names) {
public void setParameterNames(String... names) {
this.pointcutParameterNames = names;
}
/**
* Set the parameter types for the pointcut.
*/
public void setParameterTypes(Class<?>[] types) {
public void setParameterTypes(Class<?>... types) {
this.pointcutParameterTypes = types;
}
@@ -183,20 +186,13 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
throw new IllegalStateException("Must set property 'expression' before attempting to match");
}
if (this.pointcutExpression == null) {
this.pointcutExpression = buildPointcutExpression();
this.pointcutClassLoader = (this.beanFactory instanceof ConfigurableBeanFactory ?
((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader() :
ClassUtils.getDefaultClassLoader());
this.pointcutExpression = buildPointcutExpression(this.pointcutClassLoader);
}
}
/**
* Build the underlying AspectJ pointcut expression.
*/
private PointcutExpression buildPointcutExpression() {
ClassLoader cl = (this.beanFactory instanceof ConfigurableBeanFactory ? ((ConfigurableBeanFactory) this.beanFactory)
.getBeanClassLoader() : Thread.currentThread()
.getContextClassLoader());
return buildPointcutExpression(cl);
}
/**
* Build the underlying AspectJ pointcut expression.
*/
@@ -205,8 +201,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
PointcutParameter[] pointcutParameters = new PointcutParameter[this.pointcutParameterNames.length];
for (int i = 0; i < pointcutParameters.length; i++) {
pointcutParameters[i] = parser.createPointcutParameter(
this.pointcutParameterNames[i],
this.pointcutParameterTypes[i]);
this.pointcutParameterNames[i], this.pointcutParameterTypes[i]);
}
return parser.parsePointcutExpression(
replaceBooleanOperators(getExpression()),
@@ -251,24 +246,22 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
public boolean matches(Class<?> targetClass) {
checkReadyToMatch();
try {
return this.pointcutExpression.couldMatchJoinPointsInType(targetClass);
} catch (ReflectionWorldException e) {
logger.debug("PointcutExpression matching rejected target class", e);
try {
// Actually this is still a "maybe" - treat the pointcut as dynamic if we
// don't know enough yet
return getFallbackPointcutExpression(targetClass).couldMatchJoinPointsInType(targetClass);
} catch (BCException ex) {
logger.debug(
"Fallback PointcutExpression matching rejected target class",
ex);
return false;
return this.pointcutExpression.couldMatchJoinPointsInType(targetClass);
}
catch (ReflectionWorldException ex) {
logger.debug("PointcutExpression matching rejected target class - trying fallback expression", ex);
// Actually this is still a "maybe" - treat the pointcut as dynamic if we don't know enough yet
PointcutExpression fallbackExpression = getFallbackPointcutExpression(targetClass);
if (fallbackExpression != null) {
return fallbackExpression.couldMatchJoinPointsInType(targetClass);
}
}
}
catch (BCException ex) {
logger.debug("PointcutExpression matching rejected target class", ex);
return false;
}
return false;
}
@Override
@@ -288,7 +281,15 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
}
else {
// the maybe case
return (beanHasIntroductions || matchesIgnoringSubtypes(shadowMatch) || matchesTarget(shadowMatch, targetClass));
if (beanHasIntroductions) {
return true;
}
// A match test returned maybe - if there are any subtype sensitive variables
// involved in the test (this, target, at_this, at_target, at_annotation) then
// we say this is not a match as in Spring there will never be a different
// runtime subtype.
RuntimeTestWalker walker = getRuntimeTestWalker(shadowMatch);
return (!walker.testsSubtypeSensitiveVars() || walker.testTargetInstanceOfResidue(targetClass));
}
}
@@ -344,46 +345,37 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
if (!originalMethodResidueTest.testThisInstanceOfResidue(thisObject.getClass())) {
return false;
}
}
if (joinPointMatch.matches() && pmi != null) {
bindParameters(pmi, joinPointMatch);
if (joinPointMatch.matches()) {
bindParameters(pmi, joinPointMatch);
}
}
return joinPointMatch.matches();
}
protected String getCurrentProxiedBeanName() {
return ProxyCreationContext.getCurrentProxiedBeanName();
}
/**
* Get a new pointcut expression based on a target class's loader, rather
* than the default.
* Get a new pointcut expression based on a target class's loader rather than the default.
*/
private PointcutExpression getFallbackPointcutExpression(
Class<?> targetClass) {
ClassLoader classLoader = targetClass.getClassLoader();
return classLoader == null ? this.pointcutExpression : buildPointcutExpression(classLoader);
}
/**
* A match test returned maybe - if there are any subtype sensitive variables
* involved in the test (this, target, at_this, at_target, at_annotation) then
* we say this is not a match as in Spring there will never be a different
* runtime subtype.
*/
private boolean matchesIgnoringSubtypes(ShadowMatch shadowMatch) {
return !(getRuntimeTestWalker(shadowMatch).testsSubtypeSensitiveVars());
}
private boolean matchesTarget(ShadowMatch shadowMatch, Class<?> targetClass) {
return getRuntimeTestWalker(shadowMatch).testTargetInstanceOfResidue(targetClass);
private PointcutExpression getFallbackPointcutExpression(Class<?> targetClass) {
try {
ClassLoader classLoader = targetClass.getClassLoader();
if (classLoader != null && classLoader != this.pointcutClassLoader) {
return buildPointcutExpression(classLoader);
}
}
catch (Throwable ex) {
logger.debug("Failed to create fallback PointcutExpression", ex);
}
return null;
}
private RuntimeTestWalker getRuntimeTestWalker(ShadowMatch shadowMatch) {
if (shadowMatch instanceof DefensiveShadowMatch) {
return new RuntimeTestWalker(((DefensiveShadowMatch)shadowMatch).primary);
return new RuntimeTestWalker(((DefensiveShadowMatch) shadowMatch).primary);
}
return new RuntimeTestWalker(shadowMatch);
}
@@ -404,44 +396,51 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
if (shadowMatch == null) {
synchronized (this.shadowMatchCache) {
// Not found - now check again with full lock...
PointcutExpression fallbackExpression = null;
Method methodToMatch = targetMethod;
PointcutExpression fallbackPointcutExpression = null;
shadowMatch = this.shadowMatchCache.get(methodToMatch);
shadowMatch = this.shadowMatchCache.get(targetMethod);
if (shadowMatch == null) {
try {
shadowMatch = this.pointcutExpression.matchesMethodExecution(targetMethod);
shadowMatch = this.pointcutExpression.matchesMethodExecution(methodToMatch);
}
catch (ReflectionWorld.ReflectionWorldException ex) {
catch (ReflectionWorldException ex) {
// Failed to introspect target method, probably because it has been loaded
// in a special ClassLoader. Let's try the original method instead...
// in a special ClassLoader. Let's try the declaring ClassLoader instead...
try {
fallbackPointcutExpression = getFallbackPointcutExpression(methodToMatch.getDeclaringClass());
shadowMatch = fallbackPointcutExpression.matchesMethodExecution(methodToMatch);
} catch (ReflectionWorld.ReflectionWorldException e) {
if (targetMethod == originalMethod) {
shadowMatch = new ShadowMatchImpl(org.aspectj.util.FuzzyBoolean.NO, null, null, null);
fallbackExpression = getFallbackPointcutExpression(methodToMatch.getDeclaringClass());
if (fallbackExpression != null) {
shadowMatch = fallbackExpression.matchesMethodExecution(methodToMatch);
}
else {
try {
shadowMatch = this.pointcutExpression.matchesMethodExecution(originalMethod);
}
catch (ReflectionWorld.ReflectionWorldException ex2) {
// Could neither introspect the target class nor the proxy class ->
// let's simply consider this method as non-matching.
methodToMatch = originalMethod;
fallbackPointcutExpression = getFallbackPointcutExpression(methodToMatch.getDeclaringClass());
try {
shadowMatch = fallbackPointcutExpression.matchesMethodExecution(methodToMatch);
} catch (ReflectionWorld.ReflectionWorldException e2) {
shadowMatch = new ShadowMatchImpl(org.aspectj.util.FuzzyBoolean.NO, null, null, null);
}
}
catch (ReflectionWorldException ex2) {
fallbackExpression = null;
}
}
if (shadowMatch == null && targetMethod != originalMethod) {
methodToMatch = originalMethod;
try {
shadowMatch = this.pointcutExpression.matchesMethodExecution(methodToMatch);
}
catch (ReflectionWorldException ex3) {
// Could neither introspect the target class nor the proxy class ->
// let's try the original method's declaring class before we give up...
try {
fallbackExpression = getFallbackPointcutExpression(methodToMatch.getDeclaringClass());
if (fallbackExpression != null) {
shadowMatch = fallbackExpression.matchesMethodExecution(methodToMatch);
}
}
catch (ReflectionWorldException ex4) {
fallbackExpression = null;
}
}
}
if (shadowMatch.maybeMatches() && fallbackPointcutExpression!=null) {
if (shadowMatch == null) {
shadowMatch = new ShadowMatchImpl(org.aspectj.util.FuzzyBoolean.NO, null, null, null);
}
else if (shadowMatch.maybeMatches() && fallbackExpression != null) {
shadowMatch = new DefensiveShadowMatch(shadowMatch,
fallbackPointcutExpression.matchesMethodExecution(methodToMatch));
fallbackExpression.matchesMethodExecution(methodToMatch));
}
this.shadowMatchCache.put(targetMethod, shadowMatch);
}
@@ -620,9 +619,11 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
this.shadowMatchCache = new ConcurrentHashMap<Method, ShadowMatch>(32);
}
private static class DefensiveShadowMatch implements ShadowMatch {
private final ShadowMatch primary;
private final ShadowMatch other;
public DefensiveShadowMatch(ShadowMatch primary, ShadowMatch other) {
@@ -632,35 +633,34 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
@Override
public boolean alwaysMatches() {
return primary.alwaysMatches();
return this.primary.alwaysMatches();
}
@Override
public boolean maybeMatches() {
return primary.maybeMatches();
return this.primary.maybeMatches();
}
@Override
public boolean neverMatches() {
return primary.neverMatches();
return this.primary.neverMatches();
}
@Override
public JoinPointMatch matchesJoinPoint(Object thisObject,
Object targetObject, Object[] args) {
public JoinPointMatch matchesJoinPoint(Object thisObject, Object targetObject, Object[] args) {
try {
return primary.matchesJoinPoint(thisObject, targetObject, args);
} catch (ReflectionWorldException e) {
return other.matchesJoinPoint(thisObject, targetObject, args);
return this.primary.matchesJoinPoint(thisObject, targetObject, args);
}
catch (ReflectionWorldException ex) {
return this.other.matchesJoinPoint(thisObject, targetObject, args);
}
}
@Override
public void setMatchingContext(MatchingContext aMatchContext) {
primary.setMatchingContext(aMatchContext);
other.setMatchingContext(aMatchContext);
this.primary.setMatchingContext(aMatchContext);
this.other.setMatchingContext(aMatchContext);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,24 +40,24 @@ public class AspectJExpressionPointcutAdvisor extends AbstractGenericPointcutAdv
this.pointcut.setExpression(expression);
}
public String getExpression() {
return this.pointcut.getExpression();
}
public void setLocation(String location) {
this.pointcut.setLocation(location);
}
public void setParameterTypes(Class<?>[] types) {
this.pointcut.setParameterTypes(types);
}
public void setParameterNames(String[] names) {
this.pointcut.setParameterNames(names);
}
public String getLocation() {
return this.pointcut.getLocation();
}
public String getExpression() {
return this.pointcut.getExpression();
public void setParameterTypes(Class<?>[] types) {
this.pointcut.setParameterTypes(types);
}
public void setParameterNames(String... names) {
this.pointcut.setParameterNames(names);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,8 @@ package org.springframework.aop.aspectj;
import java.lang.reflect.Field;
import org.aspectj.weaver.ReferenceType;
import org.aspectj.weaver.ReferenceTypeDelegate;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.ast.And;
import org.aspectj.weaver.ast.Call;
@@ -30,6 +32,7 @@ import org.aspectj.weaver.ast.Not;
import org.aspectj.weaver.ast.Or;
import org.aspectj.weaver.ast.Test;
import org.aspectj.weaver.internal.tools.MatchingContextBasedTest;
import org.aspectj.weaver.reflect.ReflectionBasedReferenceTypeDelegate;
import org.aspectj.weaver.reflect.ReflectionVar;
import org.aspectj.weaver.reflect.ShadowMatchImpl;
import org.aspectj.weaver.tools.ShadowMatch;
@@ -55,25 +58,36 @@ import org.springframework.util.ReflectionUtils;
*/
class RuntimeTestWalker {
private static final Field residualTestField;
private static final Field varTypeField;
private static final Field myClassField;
static {
try {
residualTestField = ShadowMatchImpl.class.getDeclaredField("residualTest");
varTypeField = ReflectionVar.class.getDeclaredField("varType");
myClassField = ReflectionBasedReferenceTypeDelegate.class.getDeclaredField("myClass");
}
catch (NoSuchFieldException ex) {
throw new IllegalStateException("The version of aspectjtools.jar / aspectjweaver.jar " +
"on the classpath is incompatible with this version of Spring: " + ex);
}
}
private final Test runtimeTest;
public RuntimeTestWalker(ShadowMatch shadowMatch) {
ShadowMatchImpl shadowMatchImplementation = (ShadowMatchImpl) shadowMatch;
try {
Field testField = shadowMatchImplementation.getClass().getDeclaredField("residualTest");
ReflectionUtils.makeAccessible(testField);
this.runtimeTest = (Test) testField.get(shadowMatch);
ReflectionUtils.makeAccessible(residualTestField);
this.runtimeTest = (Test) residualTestField.get(shadowMatch);
}
catch (NoSuchFieldException noSuchFieldEx) {
throw new IllegalStateException("The version of aspectjtools.jar / aspectjweaver.jar " +
"on the classpath is incompatible with this version of Spring: Expected field " +
"'runtimeTest' is not present on ShadowMatchImpl class.");
}
catch (IllegalAccessException illegalAccessEx) {
// Famous last words... but I don't see how this can happen given the
// makeAccessible call above
throw new IllegalStateException("Unable to access ShadowMatchImpl.residualTest field");
catch (IllegalAccessException ex) {
throw new IllegalStateException(ex);
}
}
@@ -149,19 +163,11 @@ class RuntimeTestWalker {
protected int getVarType(ReflectionVar v) {
try {
Field varTypeField = ReflectionVar.class.getDeclaredField("varType");
ReflectionUtils.makeAccessible(varTypeField);
return (Integer) varTypeField.get(v);
}
catch (NoSuchFieldException noSuchFieldEx) {
throw new IllegalStateException("the version of aspectjtools.jar / aspectjweaver.jar " +
"on the classpath is incompatible with this version of Spring:- expected field " +
"'varType' is not present on ReflectionVar class");
}
catch (IllegalAccessException illegalAccessEx) {
// Famous last words... but I don't see how this can happen given the
// makeAccessible call above
throw new IllegalStateException("Unable to access ReflectionVar.varType field");
catch (IllegalAccessException ex) {
throw new IllegalStateException(ex);
}
}
}
@@ -169,9 +175,11 @@ class RuntimeTestWalker {
private static abstract class InstanceOfResidueTestVisitor extends TestVisitorAdapter {
private Class<?> matchClass;
private final Class<?> matchClass;
private boolean matches;
private int matchVarType;
private final int matchVarType;
public InstanceOfResidueTestVisitor(Class<?> matchClass, boolean defaultMatches, int matchVarType) {
this.matchClass = matchClass;
@@ -181,19 +189,34 @@ class RuntimeTestWalker {
public boolean instanceOfMatches(Test test) {
test.accept(this);
return matches;
return this.matches;
}
@Override
public void visit(Instanceof i) {
ResolvedType type = (ResolvedType) i.getType();
int varType = getVarType((ReflectionVar) i.getVar());
if (varType != this.matchVarType) {
return;
}
Class<?> typeClass = null;
ResolvedType type = (ResolvedType) i.getType();
if (type instanceof ReferenceType) {
ReferenceTypeDelegate delegate = ((ReferenceType) type).getDelegate();
if (delegate instanceof ReflectionBasedReferenceTypeDelegate) {
try {
ReflectionUtils.makeAccessible(myClassField);
typeClass = (Class<?>) myClassField.get(delegate);
}
catch (IllegalAccessException ex) {
throw new IllegalStateException(ex);
}
}
}
try {
Class<?> typeClass = ClassUtils.forName(type.getName(), this.matchClass.getClassLoader());
// Don't use ReflectionType.isAssignableFrom() as it won't be aware of (Spring) mixins
// Don't use ResolvedType.isAssignableFrom() as it won't be aware of (Spring) mixins
if (typeClass == null) {
typeClass = ClassUtils.forName(type.getName(), this.matchClass.getClassLoader());
}
this.matches = typeClass.isAssignableFrom(this.matchClass);
}
catch (ClassNotFoundException ex) {
@@ -237,8 +260,11 @@ class RuntimeTestWalker {
private static class SubtypeSensitiveVarTypeTestVisitor extends TestVisitorAdapter {
private final Object thisObj = new Object();
private final Object targetObj = new Object();
private final Object[] argsObjs = new Object[0];
private boolean testsSubtypeSensitiveVars = false;
public boolean testsSubtypeSensitiveVars(Test aTest) {
@@ -249,8 +275,8 @@ class RuntimeTestWalker {
@Override
public void visit(Instanceof i) {
ReflectionVar v = (ReflectionVar) i.getVar();
Object varUnderTest = v.getBindingAtJoinPoint(thisObj,targetObj,argsObjs);
if ((varUnderTest == thisObj) || (varUnderTest == targetObj)) {
Object varUnderTest = v.getBindingAtJoinPoint(this.thisObj, this.targetObj, this.argsObjs);
if (varUnderTest == this.thisObj || varUnderTest == this.targetObj) {
this.testsSubtypeSensitiveVars = true;
}
}
@@ -260,7 +286,7 @@ class RuntimeTestWalker {
// If you thought things were bad before, now we sink to new levels of horror...
ReflectionVar v = (ReflectionVar) hasAnn.getVar();
int varType = getVarType(v);
if ((varType == AT_THIS_VAR) || (varType == AT_TARGET_VAR) || (varType == AT_ANNOTATION_VAR)) {
if (varType == AT_THIS_VAR || varType == AT_TARGET_VAR || varType == AT_ANNOTATION_VAR) {
this.testsSubtypeSensitiveVars = true;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -67,7 +67,7 @@ public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorA
}
public void setAspectJAdvisorFactory(AspectJAdvisorFactory aspectJAdvisorFactory) {
Assert.notNull(this.aspectJAdvisorFactory, "AspectJAdvisorFactory must not be null");
Assert.notNull(aspectJAdvisorFactory, "AspectJAdvisorFactory must not be null");
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -91,9 +91,11 @@ public abstract class AbstractAdvisingBeanPostProcessor extends ProxyConfig
// Ignore AOP infrastructure such as scoped proxies.
return bean;
}
if (isEligible(bean, beanName)) {
if (bean instanceof Advised) {
Advised advised = (Advised) bean;
if (bean instanceof Advised) {
Advised advised = (Advised) bean;
if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) {
// Add our local Advisor to the existing proxy's Advisor chain...
if (this.beforeExistingAdvisors) {
advised.addAdvisor(0, this.advisor);
}
@@ -102,32 +104,47 @@ public abstract class AbstractAdvisingBeanPostProcessor extends ProxyConfig
}
return bean;
}
else {
ProxyFactory proxyFactory = new ProxyFactory(bean);
// Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
proxyFactory.copyFrom(this);
proxyFactory.addAdvisor(this.advisor);
return proxyFactory.getProxy(this.beanClassLoader);
}
}
else {
// No async proxy needed.
return bean;
if (isEligible(bean, beanName)) {
ProxyFactory proxyFactory = new ProxyFactory(bean);
// Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
proxyFactory.copyFrom(this);
proxyFactory.addAdvisor(this.advisor);
return proxyFactory.getProxy(this.beanClassLoader);
}
// No async proxy needed.
return bean;
}
/**
* Check whether the given bean is eligible for advising with this
* post-processor's {@link Advisor}.
* <p>Implements caching of {@code canApply} results per bean target class.
* <p>Delegates to {@link #isEligible(Class)} for target class checking.
* Can be overridden e.g. to specifically exclude certain beans by name.
* <p>Note: Only called for regular bean instances but not for existing
* proxy instances which implement {@link Advised} and allow for adding
* the local {@link Advisor} to the existing proxy's {@link Advisor} chain.
* For the latter, {@link #isEligible(Class)} is being called directly,
* with the actual target class behind the existing proxy (as determined
* by {@link AopUtils#getTargetClass(Object)}).
* @param bean the bean instance
* @param beanName the name of the bean
* @see AopUtils#getTargetClass(Object)
* @see AopUtils#canApply(Advisor, Class)
* @see #isEligible(Class)
*/
protected boolean isEligible(Object bean, String beanName) {
Class<?> targetClass = AopUtils.getTargetClass(bean);
return isEligible(bean.getClass());
}
/**
* Check whether the given class is eligible for advising with this
* post-processor's {@link Advisor}.
* <p>Implements caching of {@code canApply} results per bean target class.
* @param targetClass the class to check against
* @see AopUtils#canApply(Advisor, Class)
*/
protected boolean isEligible(Class<?> targetClass) {
Boolean eligible = this.eligibleBeans.get(targetClass);
if (eligible != null) {
return eligible;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,10 +32,10 @@ public interface AdvisorChainFactory {
* for the given advisor chain configuration.
* @param config the AOP configuration in the form of an Advised object
* @param method the proxied method
* @param targetClass the target class
* @param targetClass the target class (may be {@code null} to indicate a proxy without
* target object, in which case the method's declaring class is the next best option)
* @return List of MethodInterceptors (may also include InterceptorAndDynamicMethodMatchers)
*/
List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, Class<?> targetClass);
List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, Class<?> targetClass);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,7 +25,19 @@ import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.Advisor;
import org.springframework.aop.AopInvocationException;
import org.springframework.aop.PointcutAdvisor;
import org.springframework.aop.RawTargetAccess;
import org.springframework.aop.TargetSource;
import org.springframework.aop.support.AopUtils;
import org.springframework.cglib.core.CodeGenerationException;
import org.springframework.cglib.core.SpringNamingPolicy;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.CallbackFilter;
import org.springframework.cglib.proxy.Dispatcher;
@@ -34,18 +46,7 @@ import org.springframework.cglib.proxy.Factory;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.cglib.proxy.NoOp;
import org.springframework.cglib.transform.impl.MemorySafeUndeclaredThrowableStrategy;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.Advisor;
import org.springframework.aop.AopInvocationException;
import org.springframework.aop.PointcutAdvisor;
import org.springframework.aop.RawTargetAccess;
import org.springframework.aop.TargetSource;
import org.springframework.aop.support.AopUtils;
import org.springframework.cglib.transform.impl.UndeclaredThrowableStrategy;
import org.springframework.core.SmartClassLoader;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -183,19 +184,19 @@ class CglibAopProxy implements AopProxy, Serializable {
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setStrategy(new MemorySafeUndeclaredThrowableStrategy(UndeclaredThrowableException.class));
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new UndeclaredThrowableStrategy(UndeclaredThrowableException.class));
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
enhancer.setCallbackTypes(types);
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks);
@@ -219,12 +220,11 @@ class CglibAopProxy implements AopProxy, Serializable {
}
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
enhancer.setInterceptDuringConstruction(false);
enhancer.setCallbacks(callbacks);
return this.constructorArgs == null ? enhancer.create() : enhancer.create(
this.constructorArgTypes, this.constructorArgs);
return (this.constructorArgs != null ?
enhancer.create(this.constructorArgTypes, this.constructorArgs) :
enhancer.create());
}
/**
@@ -255,11 +255,14 @@ class CglibAopProxy implements AopProxy, Serializable {
* for each one found.
*/
private void doValidateClass(Class<?> proxySuperClass) {
Method[] methods = proxySuperClass.getMethods();
for (Method method : methods) {
if (!Object.class.equals(method.getDeclaringClass()) && Modifier.isFinal(method.getModifiers())) {
logger.warn("Unable to proxy method [" + method + "] because it is final: " +
"All calls to this method via a proxy will be routed directly to the proxy.");
if (logger.isWarnEnabled()) {
Method[] methods = proxySuperClass.getMethods();
for (Method method : methods) {
if (!Object.class.equals(method.getDeclaringClass()) && !Modifier.isStatic(method.getModifiers()) &&
Modifier.isFinal(method.getModifiers())) {
logger.warn("Unable to proxy method [" + method + "] because it is final: " +
"All calls to this method via a proxy will NOT be routed to the target instance.");
}
}
}
}
@@ -311,8 +314,7 @@ class CglibAopProxy implements AopProxy, Serializable {
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap<String, Integer>(methods.length);
// TODO: small memory optimisation here (can skip creation for
// methods with no advice)
// TODO: small memory optimisation here (can skip creation for methods with no advice)
for (int x = 0; x < methods.length; x++) {
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
@@ -339,16 +341,15 @@ class CglibAopProxy implements AopProxy, Serializable {
*/
private static Object processReturnType(Object proxy, Object target, Method method, Object retVal) {
// Massage return value if necessary
if (retVal != null && retVal == target &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this".
// Note that we can't help if the target sets a reference
// to itself in another returned object.
if (retVal != null && retVal == target && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this". Note that we can't help
// if the target sets a reference to itself in another returned object.
retVal = proxy;
}
Class<?> returnType = method.getReturnType();
if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
@@ -603,7 +604,7 @@ class CglibAopProxy implements AopProxy, Serializable {
*/
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
private AdvisedSupport advised;
private final AdvisedSupport advised;
public DynamicAdvisedInterceptor(AdvisedSupport advised) {
this.advised = advised;
@@ -621,8 +622,8 @@ class CglibAopProxy implements AopProxy, Serializable {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// May be null Get as late as possible to minimize the time we
// "own" the target, in case it comes from a pool.
// May be null. Get as late as possible to minimize the time we
// "own" the target, in case it comes from a pool...
target = getTarget();
if (target != null) {
targetClass = target.getClass();
@@ -688,13 +689,13 @@ class CglibAopProxy implements AopProxy, Serializable {
private final MethodProxy methodProxy;
private boolean protectedMethod;
private final boolean publicMethod;
public CglibMethodInvocation(Object proxy, Object target, Method method, Object[] arguments,
Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
this.methodProxy = methodProxy;
this.protectedMethod = Modifier.isProtected(method.getModifiers());
this.publicMethod = Modifier.isPublic(method.getModifiers());
}
/**
@@ -703,11 +704,11 @@ class CglibAopProxy implements AopProxy, Serializable {
*/
@Override
protected Object invokeJoinpoint() throws Throwable {
if (this.protectedMethod) {
return super.invokeJoinpoint();
if (this.publicMethod) {
return this.methodProxy.invoke(this.target, this.arguments);
}
else {
return this.methodProxy.invoke(this.target, this.arguments);
return super.invokeJoinpoint();
}
}
}
@@ -828,8 +829,8 @@ class CglibAopProxy implements AopProxy, Serializable {
// of the target type. If so we know it never needs to have return type
// massage and can use a dispatcher.
// If the proxy is being exposed, then must use the interceptor the
// correct one is already configured. If the target is not static cannot
// use a Dispatcher because the target can not then be released.
// correct one is already configured. If the target is not static, then
// cannot use a dispatcher because the target cannot be released.
if (exposeProxy || !isStatic) {
return INVOKE_TARGET;
}
@@ -861,7 +862,7 @@ class CglibAopProxy implements AopProxy, Serializable {
@Override
public boolean equals(Object other) {
if (other == this) {
if (this == other) {
return true;
}
if (!(other instanceof ProxyCallbackFilter)) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -50,19 +50,21 @@ public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializ
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, Class<?> targetClass) {
// This is somewhat tricky... we have to process introductions first,
// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
boolean hasIntroductions = hasMatchingIntroductions(config, targetClass);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
for (Advisor advisor : config.getAdvisors()) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(targetClass)) {
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
if (MethodMatchers.matches(mm, method, targetClass, hasIntroductions)) {
if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
@@ -78,7 +80,7 @@ public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializ
}
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(targetClass)) {
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
@@ -88,18 +90,19 @@ public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializ
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
/**
* Determine whether the Advisors contain matching introductions.
*/
private static boolean hasMatchingIntroductions(Advised config, Class<?> targetClass) {
private static boolean hasMatchingIntroductions(Advised config, Class<?> actualClass) {
for (int i = 0; i < config.getAdvisors().length; i++) {
Advisor advisor = config.getAdvisors()[i];
if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (ia.getClassFilter().matches(targetClass)) {
if (ia.getClassFilter().matches(actualClass)) {
return true;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -75,7 +75,7 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
*/
/** We use a static Log to avoid serialization issues */
private static Log logger = LogFactory.getLog(JdkDynamicAopProxy.class);
private static final Log logger = LogFactory.getLog(JdkDynamicAopProxy.class);
/** Config used to configure this proxy */
private final AdvisedSupport advised;
@@ -215,8 +215,10 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
} else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
@@ -16,9 +16,9 @@
package org.springframework.aop.framework;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.Factory;
@@ -54,15 +54,14 @@ class ObjenesisCglibAopProxy extends CglibAopProxy {
@SuppressWarnings("unchecked")
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
try {
Factory factory = (Factory) objenesis.newInstance(enhancer.createClass());
Factory factory = (Factory) this.objenesis.newInstance(enhancer.createClass());
factory.setCallbacks(callbacks);
return factory;
}
catch (ObjenesisException ex) {
// Fallback to Cglib on unsupported JVMs
// Fallback to regular proxy construction on unsupported JVMs
if (logger.isDebugEnabled()) {
logger.debug("Unable to instantiate proxy using Objenesis, falling back "
+ "to regular proxy construction", ex);
logger.debug("Unable to instantiate proxy using Objenesis, falling back to regular proxy construction", ex);
}
return super.createProxyClassAndInstance(enhancer, callbacks);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,7 +19,6 @@ package org.springframework.aop.framework;
import org.aopalliance.intercept.Interceptor;
import org.springframework.aop.TargetSource;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
@@ -47,9 +46,8 @@ public class ProxyFactory extends ProxyCreatorSupport {
* @param target the target object to be proxied
*/
public ProxyFactory(Object target) {
Assert.notNull(target, "Target object must not be null");
setInterfaces(ClassUtils.getAllInterfaces(target));
setTarget(target);
setInterfaces(ClassUtils.getAllInterfaces(target));
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -154,7 +154,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
* @see org.aopalliance.aop.Advice
* @see org.springframework.aop.target.SingletonTargetSource
*/
public void setInterceptorNames(String[] interceptorNames) {
public void setInterceptorNames(String... interceptorNames) {
this.interceptorNames = interceptorNames;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,14 +40,18 @@ import org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry;
import org.springframework.aop.target.SingletonTargetSource;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.Aware;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
/**
* {@link org.springframework.beans.factory.config.BeanPostProcessor} implementation
@@ -201,7 +205,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
* Ordering is significant: The TargetSource returned from the first matching
* TargetSourceCreator (that is, the first that returns non-null) will be used.
*/
public void setCustomTargetSourceCreators(TargetSourceCreator[] targetSourceCreators) {
public void setCustomTargetSourceCreators(TargetSourceCreator... targetSourceCreators) {
this.customTargetSourceCreators = targetSourceCreators;
}
@@ -212,7 +216,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
* This is perfectly valid, if "specific" interceptors such as matching
* Advisors are all we want.
*/
public void setInterceptorNames(String[] interceptorNames) {
public void setInterceptorNames(String... interceptorNames) {
this.interceptorNames = interceptorNames;
}
@@ -270,7 +274,9 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
@Override
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
this.earlyProxyReferences.add(cacheKey);
if (!this.earlyProxyReferences.contains(cacheKey)) {
this.earlyProxyReferences.add(cacheKey);
}
return wrapIfNecessary(bean, beanName, cacheKey);
}
@@ -465,12 +471,12 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
// Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
proxyFactory.copyFrom(this);
if (!shouldProxyTargetClass(beanClass, beanName)) {
// Must allow for introductions; can't just set interfaces to
// the target's interfaces only.
Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader);
for (Class<?> targetInterface : targetInterfaces) {
proxyFactory.addInterface(targetInterface);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
@@ -491,10 +497,8 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
}
/**
* Determine whether the given bean should be proxied with its target
* class rather than its interfaces. Checks the
* {@link #setProxyTargetClass "proxyTargetClass" setting} as well as the
* {@link AutoProxyUtils#PRESERVE_TARGET_CLASS_ATTRIBUTE "preserveTargetClass" attribute}
* Determine whether the given bean should be proxied with its target class rather than its interfaces.
* <p>Checks the {@link AutoProxyUtils#PRESERVE_TARGET_CLASS_ATTRIBUTE "preserveTargetClass" attribute}
* of the corresponding bean definition.
* @param beanClass the class of the bean
* @param beanName the name of the bean
@@ -502,9 +506,49 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
* @see AutoProxyUtils#shouldProxyTargetClass
*/
protected boolean shouldProxyTargetClass(Class<?> beanClass, String beanName) {
return (isProxyTargetClass() ||
(this.beanFactory instanceof ConfigurableListableBeanFactory &&
AutoProxyUtils.shouldProxyTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName)));
return (this.beanFactory instanceof ConfigurableListableBeanFactory &&
AutoProxyUtils.shouldProxyTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName));
}
/**
* Check the interfaces on the given bean class and apply them to the ProxyFactory,
* if appropriate.
* <p>Calls {@link #isConfigurationCallbackInterface} to filter for reasonable
* proxy interfaces, falling back to a target-class proxy otherwise.
* @param beanClass the class of the bean
* @param proxyFactory the ProxyFactory for the bean
*/
private void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader);
boolean hasReasonableProxyInterface = false;
for (Class<?> ifc : targetInterfaces) {
if (!isConfigurationCallbackInterface(ifc) && ifc.getMethods().length > 0) {
hasReasonableProxyInterface = true;
break;
}
}
if (hasReasonableProxyInterface) {
// Must allow for introductions; can't just set interfaces to the target's interfaces only.
for (Class<?> ifc : targetInterfaces) {
proxyFactory.addInterface(ifc);
}
}
else {
proxyFactory.setProxyTargetClass(true);
}
}
/**
* Determine whether the given interface is just a container callback and
* therefore not to be considered as a reasonable proxy interface.
* <p>If no reasonable proxy interface is found for a given bean, it will get
* proxied with its full target class, assuming that as the user's intention.
* @param ifc the interface to check
* @return whether the given interface is just a container callback
*/
protected boolean isConfigurationCallbackInterface(Class<?> ifc) {
return (ifc.equals(InitializingBean.class) || ifc.equals(DisposableBean.class) ||
ObjectUtils.containsElement(ifc.getInterfaces(), Aware.class));
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -60,7 +60,7 @@ public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
* @see org.springframework.beans.factory.FactoryBean
* @see org.springframework.beans.factory.BeanFactory#FACTORY_BEAN_PREFIX
*/
public void setBeanNames(String[] beanNames) {
public void setBeanNames(String... beanNames) {
Assert.notEmpty(beanNames, "'beanNames' must not be empty");
this.beanNames = new ArrayList<String>(beanNames.length);
for (String mappedName : beanNames) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2006 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,7 +25,7 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
* TargetSourceCreator that enforces a LazyInitTargetSource for each bean
* that is defined as "lazy-init". This will lead to a proxy created for
* each of those beans, allowing to fetch a reference to such a bean
* without actually initialized the target bean instance.
* without actually initializing the target bean instance.
*
* <p>To be registered as custom TargetSourceCreator for an auto-proxy creator,
* in combination with custom interceptors for specific beans or for the
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils;
@@ -81,7 +80,7 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
* Set the {@link BeanFactory} to be used when looking up executors by qualifier.
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -62,11 +62,11 @@ public class AsyncExecutionInterceptor extends AsyncExecutionAspectSupport
/**
* Create a new {@code AsyncExecutionInterceptor}.
* @param executor the {@link Executor} (typically a Spring {@link AsyncTaskExecutor}
* or {@link java.util.concurrent.ExecutorService}) to delegate to.
* @param defaultExecutor the {@link Executor} (typically a Spring {@link AsyncTaskExecutor}
* or {@link java.util.concurrent.ExecutorService}) to delegate to
*/
public AsyncExecutionInterceptor(Executor executor) {
super(executor);
public AsyncExecutionInterceptor(Executor defaultExecutor) {
super(defaultExecutor);
}
@@ -119,8 +119,8 @@ public class AsyncExecutionInterceptor extends AsyncExecutionAspectSupport
* Subclasses may override to provide support for extracting qualifier information,
* e.g. via an annotation on the given method.
* @return always {@code null}
* @see #determineAsyncExecutor(Method)
* @since 3.1.2
* @see #determineAsyncExecutor(Method)
*/
@Override
protected String getExecutorQualifier(Method method) {
@@ -258,7 +258,7 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
return returnValue;
}
catch (Throwable ex) {
if(stopWatch.isRunning()) {
if (stopWatch.isRunning()) {
stopWatch.stop();
}
exitThroughException = true;
@@ -268,7 +268,7 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
}
finally {
if (!exitThroughException) {
if(stopWatch.isRunning()) {
if (stopWatch.isRunning()) {
stopWatch.stop();
}
writeToLog(logger,
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -125,10 +125,7 @@ public class ScopedProxyFactoryBean extends ProxyConfig implements FactoryBean<O
if (this.proxy != null) {
return this.proxy.getClass();
}
if (this.scopedTargetSource != null) {
return this.scopedTargetSource.getTargetClass();
}
return null;
return this.scopedTargetSource.getTargetClass();
}
@Override
@@ -50,17 +50,17 @@ public abstract class ScopedProxyUtils {
String originalBeanName = definition.getBeanName();
BeanDefinition targetDefinition = definition.getBeanDefinition();
String targetBeanName = getTargetBeanName(originalBeanName);
// Create a scoped proxy definition for the original bean name,
// "hiding" the target bean in an internal target definition.
RootBeanDefinition proxyDefinition = new RootBeanDefinition(ScopedProxyFactoryBean.class);
proxyDefinition.setDecoratedDefinition(new BeanDefinitionHolder(targetDefinition, targetBeanName));
proxyDefinition.setOriginatingBeanDefinition(targetDefinition);
proxyDefinition.setSource(definition.getSource());
proxyDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
proxyDefinition.setRole(targetDefinition.getRole());
String targetBeanName = getTargetBeanName(originalBeanName);
proxyDefinition.getPropertyValues().add("targetBeanName", targetBeanName);
if (proxyTargetClass) {
targetDefinition.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
// ScopedProxyFactoryBean's "proxyTargetClass" default is TRUE, so we don't need to set it explicitly here.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,17 +29,16 @@ import org.springframework.util.StringUtils;
* <ul>
* <li>pattern: regular expression for the fully-qualified method names to match.
* The exact regexp syntax will depend on the subclass (e.g. Perl5 regular expressions)
* <li>patterns: alternative property taking a String array of patterns. The result will
* be the union of these patterns.
* <li>patterns: alternative property taking a String array of patterns.
* The result will be the union of these patterns.
* </ul>
*
* <p>Note: the regular expressions must be a match. For example,
* {@code .*get.*} will match com.mycom.Foo.getBar().
* {@code get.*} will not.
*
* <p>This base class is serializable. Subclasses should declare all fields transient
* - the initPatternRepresentation method in this class will be invoked again on the
* client side on deserialization.
* <p>This base class is serializable. Subclasses should declare all fields transient;
* the {@link #initPatternRepresentation} method will be invoked again on deserialization.
*
* @author Rod Johnson
* @author Juergen Hoeller
@@ -51,10 +50,14 @@ import org.springframework.util.StringUtils;
public abstract class AbstractRegexpMethodPointcut extends StaticMethodMatcherPointcut
implements Serializable {
/** Regular expressions to match */
/**
* Regular expressions to match.
*/
private String[] patterns = new String[0];
/** Regular expressions <strong>not</strong> to match */
/**
* Regular expressions <strong>not</strong> to match.
*/
private String[] excludedPatterns = new String[0];
@@ -64,15 +67,15 @@ public abstract class AbstractRegexpMethodPointcut extends StaticMethodMatcherPo
* @see #setPatterns
*/
public void setPattern(String pattern) {
setPatterns(new String[] {pattern});
setPatterns(pattern);
}
/**
* Set the regular expressions defining methods to match.
* Matching will be the union of all these; if any match,
* the pointcut matches.
* Matching will be the union of all these; if any match, the pointcut matches.
* @see #setPattern
*/
public void setPatterns(String[] patterns) {
public void setPatterns(String... patterns) {
Assert.notEmpty(patterns, "'patterns' must not be empty");
this.patterns = new String[patterns.length];
for (int i = 0; i < patterns.length; i++) {
@@ -94,15 +97,15 @@ public abstract class AbstractRegexpMethodPointcut extends StaticMethodMatcherPo
* @see #setExcludedPatterns
*/
public void setExcludedPattern(String excludedPattern) {
setExcludedPatterns(new String[] {excludedPattern});
setExcludedPatterns(excludedPattern);
}
/**
* Set the regular expressions defining methods to match for exclusion.
* Matching will be the union of all these; if any match,
* the pointcut matches.
* Matching will be the union of all these; if any match, the pointcut matches.
* @see #setExcludedPattern
*/
public void setExcludedPatterns(String[] excludedPatterns) {
public void setExcludedPatterns(String... excludedPatterns) {
Assert.notEmpty(excludedPatterns, "'excludedPatterns' must not be empty");
this.excludedPatterns = new String[excludedPatterns.length];
for (int i = 0; i < excludedPatterns.length; i++) {
@@ -173,18 +176,18 @@ public abstract class AbstractRegexpMethodPointcut extends StaticMethodMatcherPo
protected abstract void initExcludedPatternRepresentation(String[] patterns) throws IllegalArgumentException;
/**
* Does the pattern at the given index match this string?
* @param pattern {@code String} pattern to match
* @param patternIndex index of pattern from 0
* @return {@code true} if there is a match, else {@code false}.
* Does the pattern at the given index match the given String?
* @param pattern the {@code String} pattern to match
* @param patternIndex index of pattern (starting from 0)
* @return {@code true} if there is a match, {@code false} otherwise
*/
protected abstract boolean matches(String pattern, int patternIndex);
/**
* Does the exclusion pattern at the given index match this string?
* @param pattern {@code String} pattern to match.
* @param patternIndex index of pattern starting from 0.
* @return {@code true} if there is a match, else {@code false}.
* Does the exclusion pattern at the given index match the given String?
* @param pattern the {@code String} pattern to match
* @param patternIndex index of pattern (starting from 0)
* @return {@code true} if there is a match, {@code false} otherwise
*/
protected abstract boolean matchesExclusion(String pattern, int patternIndex);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@ package org.springframework.aop.support;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
@@ -215,7 +215,7 @@ public abstract class AopUtils {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
Set<Class<?>> classes = new HashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
classes.add(targetClass);
for (Class<?> clazz : classes) {
Method[] methods = clazz.getMethods();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,8 +23,7 @@ import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* Static utility methods for composing
* {@link org.springframework.aop.ClassFilter ClassFilters}.
* Static utility methods for composing {@link ClassFilter ClassFilters}.
*
* @author Rod Johnson
* @author Rob Harrop
@@ -98,8 +97,8 @@ public abstract class ClassFilters {
@Override
public boolean matches(Class<?> clazz) {
for (int i = 0; i < this.filters.length; i++) {
if (this.filters[i].matches(clazz)) {
for (ClassFilter filter : this.filters) {
if (filter.matches(clazz)) {
return true;
}
}
@@ -133,8 +132,8 @@ public abstract class ClassFilters {
@Override
public boolean matches(Class<?> clazz) {
for (int i = 0; i < this.filters.length; i++) {
if (!this.filters[i].matches(clazz)) {
for (ClassFilter filter : this.filters) {
if (!filter.matches(clazz)) {
return false;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -180,7 +180,6 @@ public class ComposablePointcut implements Pointcut, Serializable {
return this.methodMatcher;
}
@Override
public boolean equals(Object other) {
if (this == other) {
@@ -189,7 +188,6 @@ public class ComposablePointcut implements Pointcut, Serializable {
if (!(other instanceof ComposablePointcut)) {
return false;
}
ComposablePointcut that = (ComposablePointcut) other;
return ObjectUtils.nullSafeEquals(that.classFilter, this.classFilter) &&
ObjectUtils.nullSafeEquals(that.methodMatcher, this.methodMatcher);
@@ -209,8 +207,7 @@ public class ComposablePointcut implements Pointcut, Serializable {
@Override
public String toString() {
return "ComposablePointcut: ClassFilter [" + this.classFilter +
"], MethodMatcher [" + this.methodMatcher + "]";
return "ComposablePointcut: " + this.classFilter + ", " +this.methodMatcher;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,7 @@
package org.springframework.aop.support;
import java.io.Serializable;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import org.aopalliance.aop.Advice;
@@ -43,7 +43,7 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
private final Advice advice;
private final Set<Class<?>> interfaces = new HashSet<Class<?>>();
private final Set<Class<?>> interfaces = new LinkedHashSet<Class<?>>();
private int order = Integer.MAX_VALUE;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -43,7 +43,7 @@ import org.springframework.util.ClassUtils;
@SuppressWarnings("serial")
public class IntroductionInfoSupport implements IntroductionInfo, Serializable {
protected final Set<Class<?>> publishedInterfaces = new HashSet<Class<?>>();
protected final Set<Class<?>> publishedInterfaces = new LinkedHashSet<Class<?>>();
private transient Map<Method, Boolean> rememberedMethods = new ConcurrentHashMap<Method, Boolean>(32);
@@ -25,12 +25,11 @@ import org.springframework.aop.MethodMatcher;
import org.springframework.util.Assert;
/**
* Static utility methods for composing
* {@link org.springframework.aop.MethodMatcher MethodMatchers}.
* Static utility methods for composing {@link MethodMatcher MethodMatchers}.
*
* <p>A MethodMatcher may be evaluated statically (based on method
* and target class) or need further evaluation dynamically
* (based on arguments at the time of method invocation).
* <p>A MethodMatcher may be evaluated statically (based on method and target
* class) or need further evaluation dynamically (based on arguments at the
* time of method invocation).
*
* @author Rod Johnson
* @author Rob Harrop
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,7 +47,7 @@ public class NameMatchMethodPointcut extends StaticMethodMatcherPointcut impleme
* @see #setMappedNames
*/
public void setMappedName(String mappedName) {
setMappedNames(new String[] {mappedName});
setMappedNames(mappedName);
}
/**
@@ -55,7 +55,7 @@ public class NameMatchMethodPointcut extends StaticMethodMatcherPointcut impleme
* Matching will be the union of all these; if any match,
* the pointcut matches.
*/
public void setMappedNames(String[] mappedNames) {
public void setMappedNames(String... mappedNames) {
this.mappedNames = new LinkedList<String>();
if (mappedNames != null) {
this.mappedNames.addAll(Arrays.asList(mappedNames));
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -68,7 +68,7 @@ public class NameMatchMethodPointcutAdvisor extends AbstractGenericPointcutAdvis
* the pointcut matches.
* @see NameMatchMethodPointcut#setMappedNames
*/
public void setMappedNames(String[] mappedNames) {
public void setMappedNames(String... mappedNames) {
this.pointcut.setMappedNames(mappedNames);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -98,7 +98,7 @@ public class RegexpMethodPointcutAdvisor extends AbstractGenericPointcutAdvisor
* @see #setPatterns
*/
public void setPattern(String pattern) {
setPatterns(new String[] {pattern});
setPatterns(pattern);
}
/**
@@ -108,7 +108,7 @@ public class RegexpMethodPointcutAdvisor extends AbstractGenericPointcutAdvisor
* patterns matches, the pointcut matches.
* @see AbstractRegexpMethodPointcut#setPatterns
*/
public void setPatterns(String[] patterns) {
public void setPatterns(String... patterns) {
this.patterns = patterns;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -66,4 +66,26 @@ public class AnnotationClassFilter implements ClassFilter {
clazz.isAnnotationPresent(this.annotationType));
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof AnnotationClassFilter)) {
return false;
}
AnnotationClassFilter otherCf = (AnnotationClassFilter) other;
return (this.annotationType.equals(otherCf.annotationType) && this.checkInherited == otherCf.checkInherited);
}
@Override
public int hashCode() {
return this.annotationType.hashCode();
}
@Override
public String toString() {
return getClass().getName() + ": " + this.annotationType;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@ import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* Simple Pointcut that looks for a specific Java 5 annotation
@@ -100,6 +101,36 @@ public class AnnotationMatchingPointcut implements Pointcut {
return this.methodMatcher;
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof AnnotationMatchingPointcut)) {
return false;
}
AnnotationMatchingPointcut that = (AnnotationMatchingPointcut) other;
return ObjectUtils.nullSafeEquals(that.classFilter, this.classFilter) &&
ObjectUtils.nullSafeEquals(that.methodMatcher, this.methodMatcher);
}
@Override
public int hashCode() {
int code = 17;
if (this.classFilter != null) {
code = 37 * code + this.classFilter.hashCode();
}
if (this.methodMatcher != null) {
code = 37 * code + this.methodMatcher.hashCode();
}
return code;
}
@Override
public String toString() {
return "AnnotationMatchingPointcut: " + this.classFilter + ", " +this.methodMatcher;
}
/**
* Factory method for an AnnotationMatchingPointcut that matches
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -74,4 +74,9 @@ public class AnnotationMethodMatcher extends StaticMethodMatcher {
return this.annotationType.hashCode();
}
@Override
public String toString() {
return getClass().getName() + ": " + this.annotationType;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,7 +24,6 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.aop.TargetSource;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
/**
@@ -48,8 +47,7 @@ import org.springframework.util.ObjectUtils;
* @see ThreadLocalTargetSource
* @see CommonsPoolTargetSource
*/
public abstract class AbstractBeanFactoryBasedTargetSource
implements TargetSource, BeanFactoryAware, Serializable {
public abstract class AbstractBeanFactoryBasedTargetSource implements TargetSource, BeanFactoryAware, Serializable {
/** use serialVersionUID from Spring 1.2.7 for interoperability */
private static final long serialVersionUID = -4721607536018568393L;
@@ -108,7 +106,7 @@ public abstract class AbstractBeanFactoryBasedTargetSource
@Override
public void setBeanFactory(BeanFactory beanFactory) {
if (this.targetBeanName == null) {
throw new IllegalStateException("Property'targetBeanName' is required");
throw new IllegalStateException("Property 'targetBeanName' is required");
}
this.beanFactory = beanFactory;
}
@@ -185,8 +183,7 @@ public abstract class AbstractBeanFactoryBasedTargetSource
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(ClassUtils.getShortName(getClass()));
StringBuilder sb = new StringBuilder(getClass().getSimpleName());
sb.append(" for target bean '").append(this.targetBeanName).append("'");
if (this.targetClass != null) {
sb.append(" of type [").append(this.targetClass.getName()).append("]");
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -50,12 +50,10 @@ import org.springframework.beans.factory.DisposableBean;
* @see #releaseTarget
* @see #destroy
*/
@SuppressWarnings("serial")
public abstract class AbstractPoolingTargetSource extends AbstractPrototypeBasedTargetSource
implements PoolingConfig, DisposableBean {
private static final long serialVersionUID = 1L;
/** The maximum size of the pool */
private int maxSize = -1;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -43,11 +43,9 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
* @see ThreadLocalTargetSource
* @see CommonsPoolTargetSource
*/
@SuppressWarnings("serial")
public abstract class AbstractPrototypeBasedTargetSource extends AbstractBeanFactoryBasedTargetSource {
private static final long serialVersionUID = 1L;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
super.setBeanFactory(beanFactory);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,8 +24,8 @@ import org.springframework.beans.BeansException;
import org.springframework.core.Constants;
/**
* TargetSource implementation that holds objects in a configurable
* Jakarta Commons Pool.
* {@link org.springframework.aop.TargetSource} implementation that holds
* objects in a configurable Apache Commons Pool.
*
* <p>By default, an instance of {@code GenericObjectPool} is created.
* Subclasses may change the type of {@code ObjectPool} used by
@@ -40,8 +40,12 @@ import org.springframework.core.Constants;
* <p>The {@code testOnBorrow}, {@code testOnReturn} and {@code testWhileIdle}
* properties are explicitly not mirrored because the implementation of
* {@code PoolableObjectFactory} used by this class does not implement
* meaningful validation. All exposed Commons Pool properties use the corresponding
* Commons Pool defaults: for example,
* meaningful validation. All exposed Commons Pool properties use the
* corresponding Commons Pool defaults.
*
* <p>Compatible with Apache Commons Pool 1.5.x and 1.6.
* Note that this class doesn't declare Commons Pool 1.6's generic type
* in order to remain compatible with Commons Pool 1.5.x at runtime.
*
* @author Rod Johnson
* @author Rob Harrop
@@ -55,10 +59,8 @@ import org.springframework.core.Constants;
* @see #setTimeBetweenEvictionRunsMillis
* @see #setMinEvictableIdleTimeMillis
*/
public class CommonsPoolTargetSource extends AbstractPoolingTargetSource
implements PoolableObjectFactory {
private static final long serialVersionUID = 1L;
@SuppressWarnings({"rawtypes", "unchecked", "serial"})
public class CommonsPoolTargetSource extends AbstractPoolingTargetSource implements PoolableObjectFactory {
private static final Constants constants = new Constants(GenericObjectPool.class);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,9 +19,11 @@ package org.springframework.aop.target;
import org.springframework.beans.BeansException;
/**
* TargetSource that creates a new instance of the target bean for each
* request, destroying each instance on release (after each request).
* Obtains bean instances from its containing
* {@link org.springframework.aop.TargetSource} implementation that
* creates a new instance of the target bean for each request,
* destroying each instance on release (after each request).
*
* <p>Obtains bean instances from its containing
* {@link org.springframework.beans.factory.BeanFactory}.
*
* @author Rod Johnson
@@ -29,10 +31,9 @@ import org.springframework.beans.BeansException;
* @see #setBeanFactory
* @see #setTargetBeanName
*/
@SuppressWarnings("serial")
public class PrototypeTargetSource extends AbstractPrototypeBasedTargetSource {
private static final long serialVersionUID = 1L;
/**
* Obtain a new prototype instance for every call.
* @see #newPrototypeInstance()
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,9 +27,10 @@ import org.springframework.beans.factory.DisposableBean;
import org.springframework.core.NamedThreadLocal;
/**
* Alternative to an object pool. This TargetSource uses a threading model in which
* every thread has its own copy of the target. There's no contention for targets.
* Target object creation is kept to a minimum on the running server.
* Alternative to an object pool. This {@link org.springframework.aop.TargetSource}
* uses a threading model in which every thread has its own copy of the target.
* There's no contention for targets. Target object creation is kept to a minimum
* on the running server.
*
* <p>Application code is written as to a normal pool; callers can't assume they
* will be dealing with the same instance in invocations in different threads.
@@ -47,11 +48,10 @@ import org.springframework.core.NamedThreadLocal;
* @see ThreadLocalTargetSourceStats
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
@SuppressWarnings("serial")
public class ThreadLocalTargetSource extends AbstractPrototypeBasedTargetSource
implements ThreadLocalTargetSourceStats, DisposableBean {
private static final long serialVersionUID = 1L;
/**
* ThreadLocal holding the target associated with the current
* thread. Unlike most ThreadLocals, which are static, this variable
@@ -81,10 +81,8 @@ public class ThreadLocalTargetSource extends AbstractPrototypeBasedTargetSource
Object target = this.targetInThread.get();
if (target == null) {
if (logger.isDebugEnabled()) {
logger.debug("No target for prototype '" + getTargetBeanName() +
"' bound to thread: " +
"creating one and binding it to thread '" +
Thread.currentThread().getName() + "'");
logger.debug("No target for prototype '" + getTargetBeanName() + "' bound to thread: " +
"creating one and binding it to thread '" + Thread.currentThread().getName() + "'");
}
// Associate target with ThreadLocal.
target = newPrototypeInstance();
@@ -197,7 +197,7 @@
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="order" type="xsd:int">
<xsd:attribute name="order" type="xsd:token">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.core.Ordered"><![CDATA[
Controls the ordering of the execution of this aspect when multiple
@@ -386,7 +386,7 @@
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="order" type="xsd:int">
<xsd:attribute name="order" type="xsd:token">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.core.Ordered"><![CDATA[
Controls the ordering of the execution of this advice when multiple
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,15 +15,6 @@
*/
package org.springframework.aop.aspectj.annotation;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.FileNotFoundException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -46,7 +37,9 @@ import org.aspectj.lang.annotation.DeclareParents;
import org.aspectj.lang.annotation.DeclarePrecedence;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.junit.Test;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor;
import org.springframework.aop.framework.Advised;
@@ -66,6 +59,9 @@ import test.aop.Lockable;
import test.aop.PerTargetAspect;
import test.aop.TwoAdviceAspect;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
/**
* Abstract tests for AspectJAdvisorFactory.
* See subclasses for tests of concrete factories.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,10 +16,6 @@
package org.springframework.aop.support;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import org.junit.Before;
@@ -27,6 +23,8 @@ import org.junit.Test;
import org.springframework.tests.sample.beans.TestBean;
import org.springframework.util.SerializationTestUtils;
import static org.junit.Assert.*;
/**
* @author Rod Johnson
* @author Dmitriy Kopylenko
@@ -0,0 +1,10 @@
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{HH:mm:ss,SSS} [%c] - %m%n
log4j.rootCategory=WARN, console
log4j.logger.org.springframework.beans=WARN
log4j.logger.org.springframework.binding=DEBUG
#log4j.logger.org.springframework.aop=TRACE
-28
View File
@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- Appenders -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p: %c - %m%n" />
</layout>
</appender>
<logger name="org.springframework.beans">
<level value="warn" />
</logger>
<logger name="org.springframework.binding">
<level value="debug" />
</logger>
<!-- Root Logger -->
<root>
<priority value="warn" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
+1 -1
View File
@@ -61,7 +61,7 @@ compileTestJava {
ant.taskdef(resource: "org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties",
classpath: configurations.ajc.asPath)
ant.iajc(source: compileJava.sourceCompatibility, target: compileJava.targetCompatibility,
ant.iajc(source: sourceCompatibility, target: targetCompatibility,
maxmem: "1024m", fork: "true", Xlint: "ignore",
destDir: outputDir.absolutePath,
aspectPath: jar.archivePath,
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,26 +27,18 @@ import org.aspectj.lang.annotation.control.CodeGenerationHint;
* @since 2.5.2
*/
public abstract aspect AbstractDependencyInjectionAspect {
/**
* Select construction join points for objects to inject dependencies
*/
public abstract pointcut beanConstruction(Object bean);
private pointcut preConstructionCondition() :
leastSpecificSuperTypeConstruction() && preConstructionConfiguration();
private pointcut postConstructionCondition() :
mostSpecificSubTypeConstruction() && !preConstructionConfiguration();
/**
* Select deserialization join points for objects to inject dependencies
* Select least specific super type that is marked for DI
* (so that injection occurs only once with pre-construction injection).
*/
public abstract pointcut beanDeserialization(Object bean);
/**
* Select join points in a configurable bean
*/
public abstract pointcut inConfigurableBean();
/**
* Select join points in beans to be configured prior to construction?
* By default, use post-construction injection matching the default in the Configurable annotation.
*/
public pointcut preConstructionConfiguration() : if(false);
public abstract pointcut leastSpecificSuperTypeConstruction();
/**
* Select the most-specific initialization join point
@@ -54,24 +46,29 @@ public abstract aspect AbstractDependencyInjectionAspect {
*/
@CodeGenerationHint(ifNameSuffix="6f1")
public pointcut mostSpecificSubTypeConstruction() :
if(thisJoinPoint.getSignature().getDeclaringType() == thisJoinPoint.getThis().getClass());
if (thisJoinPoint.getSignature().getDeclaringType() == thisJoinPoint.getThis().getClass());
/**
* Select least specific super type that is marked for DI (so that injection occurs only once with pre-construction inejection
* Select join points in beans to be configured prior to construction?
* By default, use post-construction injection matching the default in the Configurable annotation.
*/
public abstract pointcut leastSpecificSuperTypeConstruction();
public pointcut preConstructionConfiguration() : if (false);
/**
* Configure the bean
* Select construction join points for objects to inject dependencies.
*/
public abstract void configureBean(Object bean);
public abstract pointcut beanConstruction(Object bean);
/**
* Select deserialization join points for objects to inject dependencies.
*/
public abstract pointcut beanDeserialization(Object bean);
private pointcut preConstructionCondition() :
leastSpecificSuperTypeConstruction() && preConstructionConfiguration();
/**
* Select join points in a configurable bean.
*/
public abstract pointcut inConfigurableBean();
private pointcut postConstructionCondition() :
mostSpecificSubTypeConstruction() && !preConstructionConfiguration();
/**
* Pre-construction configuration.
@@ -100,4 +97,10 @@ public abstract aspect AbstractDependencyInjectionAspect {
configureBean(bean);
}
/**
* Configure the given bean.
*/
public abstract void configureBean(Object bean);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,49 +20,48 @@ import java.io.ObjectStreamException;
import java.io.Serializable;
/**
* An aspect that injects dependency into any object whose type implements the {@link ConfigurableObject} interface.
* <p>
* This aspect supports injecting into domain objects when they are created for the first time as well as
* upon deserialization. Subaspects need to simply provide definition for the configureBean() method. This
* method may be implemented without relying on Spring container if so desired.
* </p>
* <p>
* There are two cases that needs to be handled:
* An aspect that injects dependency into any object whose type implements the
* {@link ConfigurableObject} interface.
*
* <p>This aspect supports injecting into domain objects when they are created
* for the first time as well as upon deserialization. Subaspects need to simply
* provide definition for the configureBean() method. This method may be
* implemented without relying on Spring container if so desired.
*
* <p>There are two cases that needs to be handled:
* <ol>
* <li>Normal object creation via the '{@code new}' operator: this is
* taken care of by advising {@code initialization()} join points.</li>
* <li>Object creation through deserialization: since no constructor is
* invoked during deserialization, the aspect needs to advise a method that a
* deserialization mechanism is going to invoke. Ideally, we should not
* require user classes to implement any specific method. This implies that
* we need to <i>introduce</i> the chosen method. We should also handle the cases
* where the chosen method is already implemented in classes (in which case,
* the user's implementation for that method should take precedence over the
* introduced implementation). There are a few choices for the chosen method:
* <ul>
* <li>readObject(ObjectOutputStream): Java requires that the method must be
* {@code private}</p>. Since aspects cannot introduce a private member,
* while preserving its name, this option is ruled out.</li>
* <li>readResolve(): Java doesn't pose any restriction on an access specifier.
* Problem solved! There is one (minor) limitation of this approach in
* that if a user class already has this method, that method must be
* {@code public}. However, this shouldn't be a big burden, since
* use cases that need classes to implement readResolve() (custom enums,
* for example) are unlikely to be marked as &#64;Configurable, and
* in any case asking to make that method {@code public} should not
* pose any undue burden.</li>
* </ul>
* The minor collaboration needed by user classes (i.e., that the
* implementation of {@code readResolve()}, if any, must be
* {@code public}) can be lifted as well if we were to use an
* experimental feature in AspectJ - the {@code hasmethod()} PCD.</li>
* <li>Normal object creation via the '{@code new}' operator: this is
* taken care of by advising {@code initialization()} join points.</li>
* <li>Object creation through deserialization: since no constructor is
* invoked during deserialization, the aspect needs to advise a method that a
* deserialization mechanism is going to invoke. Ideally, we should not
* require user classes to implement any specific method. This implies that
* we need to <i>introduce</i> the chosen method. We should also handle the cases
* where the chosen method is already implemented in classes (in which case,
* the user's implementation for that method should take precedence over the
* introduced implementation). There are a few choices for the chosen method:
* <ul>
* <li>readObject(ObjectOutputStream): Java requires that the method must be
* {@code private}</p>. Since aspects cannot introduce a private member,
* while preserving its name, this option is ruled out.</li>
* <li>readResolve(): Java doesn't pose any restriction on an access specifier.
* Problem solved! There is one (minor) limitation of this approach in
* that if a user class already has this method, that method must be
* {@code public}. However, this shouldn't be a big burden, since
* use cases that need classes to implement readResolve() (custom enums,
* for example) are unlikely to be marked as &#64;Configurable, and
* in any case asking to make that method {@code public} should not
* pose any undue burden.</li>
* </ul>
* The minor collaboration needed by user classes (i.e., that the implementation of
* {@code readResolve()}, if any, must be {@code public}) can be lifted as well if we
* were to use an experimental feature in AspectJ - the {@code hasmethod()} PCD.</li>
* </ol>
* <p>
* While having type implement the {@link ConfigurableObject} interface is certainly a valid choice, an alternative
* is to use a 'declare parents' statement another aspect (a subaspect of this aspect would be a logical choice)
* that declares the classes that need to be configured by supplying the {@link ConfigurableObject} interface.
* </p>
*
* <p>While having type implement the {@link ConfigurableObject} interface is certainly
* a valid choice, an alternative is to use a 'declare parents' statement another aspect
* (a subaspect of this aspect would be a logical choice) that declares the classes that
* need to be configured by supplying the {@link ConfigurableObject} interface.
*
* @author Ramnivas Laddad
* @since 2.5.2
@@ -72,35 +71,33 @@ public abstract aspect AbstractInterfaceDrivenDependencyInjectionAspect extends
* Select initialization join point as object construction
*/
public pointcut beanConstruction(Object bean) :
initialization(ConfigurableObject+.new(..)) && this(bean);
initialization(ConfigurableObject+.new(..)) && this(bean);
/**
* Select deserialization join point made available through ITDs for ConfigurableDeserializationSupport
*/
public pointcut beanDeserialization(Object bean) :
execution(Object ConfigurableDeserializationSupport+.readResolve()) &&
this(bean);
execution(Object ConfigurableDeserializationSupport+.readResolve()) && this(bean);
public pointcut leastSpecificSuperTypeConstruction() : initialization(ConfigurableObject.new(..));
// Implementation to support re-injecting dependencies once an object is deserialized
/**
* Declare any class implementing Serializable and ConfigurableObject as also implementing
* ConfigurableDeserializationSupport. This allows us to introduce the readResolve()
* ConfigurableDeserializationSupport. This allows us to introduce the {@code readResolve()}
* method and select it with the beanDeserialization() pointcut.
*
* <p>Here is an improved version that uses the hasmethod() pointcut and lifts
* even the minor requirement on user classes:
*
* <pre class="code">declare parents: ConfigurableObject+ Serializable+
* && !hasmethod(Object readResolve() throws ObjectStreamException)
* implements ConfigurableDeserializationSupport;
* <pre class="code">
* declare parents: ConfigurableObject+ Serializable+
* && !hasmethod(Object readResolve() throws ObjectStreamException)
* implements ConfigurableDeserializationSupport;
* </pre>
*/
declare parents:
ConfigurableObject+ && Serializable+ implements ConfigurableDeserializationSupport;
declare parents: ConfigurableObject+ && Serializable+ implements ConfigurableDeserializationSupport;
/**
* A marker interface to which the {@code readResolve()} is introduced.
@@ -111,7 +108,6 @@ public abstract aspect AbstractInterfaceDrivenDependencyInjectionAspect extends
/**
* Introduce the {@code readResolve()} method so that we can advise its
* execution to configure the object.
*
* <p>Note if a method with the same signature already exists in a
* {@code Serializable} class of ConfigurableObject type,
* that implementation will take precedence (a good thing, since we are
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@ package org.springframework.beans.factory.aspectj;
import java.io.Serializable;
import org.aspectj.lang.annotation.control.CodeGenerationHint;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.DisposableBean;
@@ -44,48 +44,47 @@ import org.springframework.beans.factory.wiring.BeanConfigurerSupport;
* @see org.springframework.beans.factory.annotation.Configurable
* @see org.springframework.beans.factory.annotation.AnnotationBeanWiringInfoResolver
*/
public aspect AnnotationBeanConfigurerAspect
extends AbstractInterfaceDrivenDependencyInjectionAspect
public aspect AnnotationBeanConfigurerAspect extends AbstractInterfaceDrivenDependencyInjectionAspect
implements BeanFactoryAware, InitializingBean, DisposableBean {
private BeanConfigurerSupport beanConfigurerSupport = new BeanConfigurerSupport();
public void setBeanFactory(BeanFactory beanFactory) {
this.beanConfigurerSupport.setBeanWiringInfoResolver(new AnnotationBeanWiringInfoResolver());
this.beanConfigurerSupport.setBeanFactory(beanFactory);
}
public void afterPropertiesSet() throws Exception {
this.beanConfigurerSupport.afterPropertiesSet();
}
public void configureBean(Object bean) {
this.beanConfigurerSupport.configureBean(bean);
}
public void destroy() throws Exception {
this.beanConfigurerSupport.destroy();
}
public pointcut inConfigurableBean() : @this(Configurable);
public pointcut preConstructionConfiguration() : preConstructionConfigurationSupport(*);
declare parents: @Configurable * implements ConfigurableObject;
public void configureBean(Object bean) {
beanConfigurerSupport.configureBean(bean);
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
beanConfigurerSupport.setBeanFactory(beanFactory);
beanConfigurerSupport.setBeanWiringInfoResolver(new AnnotationBeanWiringInfoResolver());
}
public void afterPropertiesSet() throws Exception {
beanConfigurerSupport.afterPropertiesSet();
}
public void destroy() throws Exception {
beanConfigurerSupport.destroy();
}
/*
* An intermediary to match preConstructionConfiguration signature (that doesn't expose the annotation object)
*/
@CodeGenerationHint(ifNameSuffix="bb0")
private pointcut preConstructionConfigurationSupport(Configurable c) : @this(c) && if(c.preConstruction());
private pointcut preConstructionConfigurationSupport(Configurable c) : @this(c) && if (c.preConstruction());
declare parents: @Configurable * implements ConfigurableObject;
/*
* This declaration shouldn't be needed,
* except for an AspectJ bug (https://bugs.eclipse.org/bugs/show_bug.cgi?id=214559)
*/
declare parents: @Configurable Serializable+
implements ConfigurableDeserializationSupport;
declare parents: @Configurable Serializable+ implements ConfigurableDeserializationSupport;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,7 +35,7 @@ import org.springframework.context.annotation.Role;
@Configuration
public class AspectJCachingConfiguration extends AbstractCachingConfiguration {
@Bean(name=AnnotationConfigUtils.CACHE_ASPECT_BEAN_NAME)
@Bean(name = AnnotationConfigUtils.CACHE_ASPECT_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public AnnotationCacheAspect cacheAspect() {
AnnotationCacheAspect cacheAspect = AnnotationCacheAspect.aspectOf();
@@ -47,4 +47,5 @@ public class AspectJCachingConfiguration extends AbstractCachingConfiguration {
}
return cacheAspect;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,86 +18,140 @@ package org.springframework.mock.staticmock;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import org.springframework.util.ObjectUtils;
/**
* Abstract aspect to enable mocking of methods picked out by a pointcut.
* Sub-aspects must define the mockStaticsTestMethod() pointcut to
* indicate call stacks when mocking should be triggered, and the
* methodToMock() pointcut to pick out a method invocations to mock.
*
* <p>Sub-aspects must define:
* <ul>
* <li>The {@link #mockStaticsTestMethod()} pointcut to indicate call stacks
* when mocking should be triggered
* <li>The {@link #methodToMock()} pointcut to pick out method invocations to mock
* </ul>
*
* @author Rod Johnson
* @author Ramnivas Laddad
* @author Sam Brannen
*/
public abstract aspect AbstractMethodMockingControl percflow(mockStaticsTestMethod()) {
protected abstract pointcut mockStaticsTestMethod();
protected abstract pointcut methodToMock();
private final Expectations expectations = new Expectations();
private boolean recording = true;
static enum CallResponse { nothing, return_, throw_ };
// Represents a list of expected calls to static entity methods
protected void expectReturnInternal(Object retVal) {
if (!recording) {
throw new IllegalStateException("Not recording: Cannot set return value");
}
expectations.expectReturn(retVal);
}
protected void expectThrowInternal(Throwable throwable) {
if (!recording) {
throw new IllegalStateException("Not recording: Cannot set throwable value");
}
expectations.expectThrow(throwable);
}
protected void playbackInternal() {
recording = false;
}
protected void verifyInternal() {
expectations.verify();
}
protected void resetInternal() {
expectations.reset();
recording = true;
}
private static enum CallResponse {
undefined, return_, throw_
};
/**
* Represents a list of expected calls to methods.
*/
// Public to allow inserted code to access: is this normal??
public class Expectations {
// Represents an expected call to a static entity method
/**
* Represents an expected call to a method.
*/
private class Call {
private final String signature;
private final Object[] args;
private CallResponse responseType = CallResponse.undefined;
private Object responseObject; // return value or throwable
private CallResponse responseType = CallResponse.nothing;
public Call(String name, Object[] args) {
this.signature = name;
Call(String signature, Object[] args) {
this.signature = signature;
this.args = args;
}
public boolean hasResponseSpecified() {
return responseType != CallResponse.nothing;
boolean responseTypeAlreadySet() {
return responseType != CallResponse.undefined;
}
public void setReturnVal(Object retVal) {
void setReturnValue(Object retVal) {
this.responseObject = retVal;
responseType = CallResponse.return_;
}
public void setThrow(Throwable throwable) {
void setThrowable(Throwable throwable) {
this.responseObject = throwable;
responseType = CallResponse.throw_;
}
public Object returnValue(String lastSig, Object[] args) {
Object returnValue(String lastSig, Object[] args) {
checkSignature(lastSig, args);
return responseObject;
}
public Object throwException(String lastSig, Object[] args) {
Object throwException(String lastSig, Object[] args) {
checkSignature(lastSig, args);
throw (RuntimeException)responseObject;
throw (RuntimeException) responseObject;
}
private void checkSignature(String lastSig, Object[] args) {
if (!signature.equals(lastSig)) {
throw new IllegalArgumentException("Signature doesn't match");
throw new IllegalArgumentException("Signatures do not match");
}
if (!Arrays.equals(this.args, args)) {
throw new IllegalArgumentException("Arguments don't match");
throw new IllegalArgumentException("Arguments do not match");
}
}
@Override
public String toString() {
return String.format("Call with signature [%s] and arguments %s", this.signature,
ObjectUtils.nullSafeToString(args));
}
}
private List<Call> calls = new LinkedList<Call>();
// Calls already verified
/**
* The list of recorded calls.
*/
private final LinkedList<Call> calls = new LinkedList<Call>();
/**
* The number of calls already verified.
*/
private int verified;
public void verify() {
if (verified != calls.size()) {
throw new IllegalStateException("Expected " + calls.size() + " calls, received " + verified);
throw new IllegalStateException("Expected " + calls.size() + " calls, but received " + verified);
}
}
@@ -105,31 +159,32 @@ public abstract aspect AbstractMethodMockingControl percflow(mockStaticsTestMeth
* Validate the call and provide the expected return value.
*/
public Object respond(String lastSig, Object[] args) {
Call call = nextCall();
CallResponse responseType = call.responseType;
if (responseType == CallResponse.return_) {
return call.returnValue(lastSig, args);
Call c = nextCall();
switch (c.responseType) {
case return_: {
return c.returnValue(lastSig, args);
}
case throw_: {
return c.throwException(lastSig, args);
}
default: {
throw new IllegalStateException("Behavior of " + c + " not specified");
}
}
else if (responseType == CallResponse.throw_) {
return call.throwException(lastSig, args);
}
else if (responseType == CallResponse.nothing) {
// do nothing
}
throw new IllegalStateException("Behavior of " + call + " not specified");
}
private Call nextCall() {
verified++;
if (verified > calls.size()) {
throw new IllegalStateException("Expected " + calls.size() + " calls, received " + verified);
throw new IllegalStateException("Expected " + calls.size() + " calls, but received " + verified);
}
return calls.get(verified);
// The 'verified' count is 1-based; whereas, 'calls' is 0-based.
return calls.get(verified - 1);
}
public void expectCall(String lastSig, Object lastArgs[]) {
Call call = new Call(lastSig, lastArgs);
calls.add(call);
public void expectCall(String lastSig, Object[] lastArgs) {
calls.add(new Call(lastSig, lastArgs));
}
public boolean hasCalls() {
@@ -137,31 +192,48 @@ public abstract aspect AbstractMethodMockingControl percflow(mockStaticsTestMeth
}
public void expectReturn(Object retVal) {
Call call = calls.get(calls.size() - 1);
if (call.hasResponseSpecified()) {
throw new IllegalStateException("No static method invoked before setting return value");
Call c = calls.getLast();
if (c.responseTypeAlreadySet()) {
throw new IllegalStateException("No method invoked before setting return value");
}
call.setReturnVal(retVal);
c.setReturnValue(retVal);
}
public void expectThrow(Throwable throwable) {
Call call = calls.get(calls.size() - 1);
if (call.hasResponseSpecified()) {
throw new IllegalStateException("No static method invoked before setting throwable");
Call c = calls.getLast();
if (c.responseTypeAlreadySet()) {
throw new IllegalStateException("No method invoked before setting throwable");
}
call.setThrow(throwable);
c.setThrowable(throwable);
}
/**
* Reset the internal state of this {@code Expectations} instance.
*/
public void reset() {
this.calls.clear();
this.verified = 0;
}
}
private Expectations expectations = new Expectations();
/**
* Pointcut that identifies call stacks when mocking should be triggered.
*/
protected abstract pointcut mockStaticsTestMethod();
/**
* Pointcut that identifies which method invocations to mock.
*/
protected abstract pointcut methodToMock();
after() returning : mockStaticsTestMethod() {
if (recording && (expectations.hasCalls())) {
throw new IllegalStateException(
"Calls recorded, yet playback state never reached: Create expectations then call "
+ this.getClass().getSimpleName() + ".playback()");
"Calls have been recorded, but playback state was never reached. Set expectations and then call "
+ this.getClass().getSimpleName() + ".playback();");
}
expectations.verify();
verifyInternal();
}
Object around() : methodToMock() && cflowbelow(mockStaticsTestMethod()) {
@@ -175,22 +247,4 @@ public abstract aspect AbstractMethodMockingControl percflow(mockStaticsTestMeth
}
}
public void expectReturnInternal(Object retVal) {
if (!recording) {
throw new IllegalStateException("Not recording: Cannot set return value");
}
expectations.expectReturn(retVal);
}
public void expectThrowInternal(Throwable throwable) {
if (!recording) {
throw new IllegalStateException("Not recording: Cannot set throwable value");
}
expectations.expectThrow(throwable);
}
public void playbackInternal() {
recording = false;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,50 +17,98 @@
package org.springframework.mock.staticmock;
/**
* Annotation-based aspect to use in test build to enable mocking static methods
* on JPA-annotated {@code @Entity} classes, as used by Roo for finders.
* Annotation-based aspect to use in test builds to enable mocking of static methods
* on JPA-annotated {@code @Entity} classes, as used by Spring Roo for so-called
* <em>finder methods</em>.
*
* <p>Mocking will occur in the call stack of any method in a class (typically a test class)
* that is annotated with the @MockStaticEntityMethods annotation.
* <p>Mocking will occur within the call stack of any {@code public} method in a
* class (typically a test class) that is annotated with {@code @MockStaticEntityMethods}.
* Thus mocking is not limited to {@code @Test} methods. Furthermore, new mock
* state will be created for the invocation of each such public method, even when
* the method is invoked from another such public method.
*
* <p>Also provides static methods to simplify the programming model for
* entering playback mode and setting expected return values.
* <p>This aspect also provides static methods to simplify the programming model for
* setting expectations and entering playback mode.
*
* <p>Usage:
* <h3>Usage</h3>
* <ol>
* <li>Annotate a test class with @MockStaticEntityMethods.
* <li>In each test method, AnnotationDrivenStaticEntityMockingControl will begin in recording mode.
* Invoke static methods on Entity classes, with each recording-mode invocation
* being followed by an invocation to the static expectReturn() or expectThrow()
* method on AnnotationDrivenStaticEntityMockingControl.
* <li>Invoke the static AnnotationDrivenStaticEntityMockingControl() method.
* <li>Call the code you wish to test that uses the static methods. Verification will
* occur automatically.
* <li>Annotate a test class with {@code @MockStaticEntityMethods}.
* <li>In each test method, the {@code AnnotationDrivenStaticEntityMockingControl}
* will begin in <em>recording</em> mode.
* <li>Invoke static methods on JPA-annotated {@code @Entity} classes, with each
* recording-mode invocation being followed by an invocation of either
* {@link #expectReturn(Object)} or {@link #expectThrow(Throwable)} on the
* {@code AnnotationDrivenStaticEntityMockingControl}.
* <li>Invoke the {@link #playback()} method.
* <li>Call the code you wish to test that uses the static methods on the
* JPA-annotated {@code @Entity} classes.
* <li>Verification will occur automatically after the test method has executed
* and returned. However, mock verification will not occur if the test method
* throws an exception.
* </ol>
*
* <h3>Programmatic Control of the Mock</h3>
* <p>For scenarios where it would be convenient to programmatically <em>verify</em>
* the recorded expectations or <em>reset</em> the state of the mock, consider
* using combinations of {@link #verify()} and {@link #reset()}.
*
* @author Rod Johnson
* @author Ramnivas Laddad
* @author Sam Brannen
* @see MockStaticEntityMethods
*/
public aspect AnnotationDrivenStaticEntityMockingControl extends AbstractMethodMockingControl {
/**
* Stop recording mock calls and enter playback state
* Expect the supplied {@link Object} to be returned by the previous static
* method invocation.
* @see #playback()
*/
public static void expectReturn(Object retVal) {
AnnotationDrivenStaticEntityMockingControl.aspectOf().expectReturnInternal(retVal);
}
/**
* Expect the supplied {@link Throwable} to be thrown by the previous static
* method invocation.
* @see #playback()
*/
public static void expectThrow(Throwable throwable) {
AnnotationDrivenStaticEntityMockingControl.aspectOf().expectThrowInternal(throwable);
}
/**
* Stop recording mock expectations and enter <em>playback</em> mode.
* @see #expectReturn(Object)
* @see #expectThrow(Throwable)
*/
public static void playback() {
AnnotationDrivenStaticEntityMockingControl.aspectOf().playbackInternal();
}
public static void expectReturn(Object retVal) {
AnnotationDrivenStaticEntityMockingControl.aspectOf().expectReturnInternal(retVal);
/**
* Verify that all expectations have been fulfilled.
* @since 4.0.2
* @see #reset()
*/
public static void verify() {
AnnotationDrivenStaticEntityMockingControl.aspectOf().verifyInternal();
}
public static void expectThrow(Throwable throwable) {
AnnotationDrivenStaticEntityMockingControl.aspectOf().expectThrowInternal(throwable);
/**
* Reset the state of the mock and enter <em>recording</em> mode.
* @since 4.0.2
* @see #verify()
*/
public static void reset() {
AnnotationDrivenStaticEntityMockingControl.aspectOf().resetInternal();
}
// Only matches directly annotated @Test methods, to allow methods in
// @MockStatics classes to invoke each other without resetting the mocking environment
// Apparently, the following pointcut was originally defined to only match
// methods directly annotated with @Test (in order to allow methods in
// @MockStaticEntityMethods classes to invoke each other without creating a
// new mocking environment); however, this is no longer the case. The current
// pointcut applies to all public methods in @MockStaticEntityMethods classes.
protected pointcut mockStaticsTestMethod() : execution(public * (@MockStaticEntityMethods *).*(..));
protected pointcut methodToMock() : execution(public static * (@javax.persistence.Entity *).*(..));
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,11 +22,13 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation to indicate a test class for whose @Test methods
* static methods on Entity classes should be mocked. See
* {@code AbstractMethodMockingControl}.
* Annotation to indicate a test class for whose {@code @Test} methods
* static methods on JPA-annotated {@code @Entity} classes should be mocked.
*
* <p>See {@link AnnotationDrivenStaticEntityMockingControl} for details.
*
* @author Rod Johnson
* @author Sam Brannen
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,11 +32,12 @@ import org.springframework.scheduling.annotation.EnableAsync;
* @since 3.1
* @see EnableAsync
* @see org.springframework.scheduling.annotation.AsyncConfigurationSelector
* @see org.springframework.scheduling.annotation.ProxyAsyncConfiguration
*/
@Configuration
public class AspectJAsyncConfiguration extends AbstractAsyncConfiguration {
@Bean(name=AnnotationConfigUtils.ASYNC_EXECUTION_ASPECT_BEAN_NAME)
@Bean(name = AnnotationConfigUtils.ASYNC_EXECUTION_ASPECT_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public AnnotationAsyncExecutionAspect asyncAdvisor() {
AnnotationAsyncExecutionAspect asyncAspect = AnnotationAsyncExecutionAspect.aspectOf();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,7 +37,7 @@ import org.springframework.transaction.config.TransactionManagementConfigUtils;
@Configuration
public class AspectJTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
@Bean(name=TransactionManagementConfigUtils.TRANSACTION_ASPECT_BEAN_NAME)
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ASPECT_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public AnnotationTransactionAspect transactionAspect() {
AnnotationTransactionAspect txAspect = AnnotationTransactionAspect.aspectOf();
@@ -46,4 +46,5 @@ public class AspectJTransactionManagementConfiguration extends AbstractTransacti
}
return txAspect;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,6 @@ package org.springframework.cache.config;
import org.springframework.cache.interceptor.DefaultKeyGenerator;
@SuppressWarnings("deprecation")
public class SomeKeyGenerator extends DefaultKeyGenerator {
}
@@ -1,147 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.mock.staticmock;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl.expectReturn;
import static org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl.expectThrow;
import static org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl.playback;
import javax.persistence.PersistenceException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/**
* Test for static entity mocking framework.
* @author Rod Johnson
* @author Ramnivas Laddad
*
*/
@MockStaticEntityMethods
@RunWith(JUnit4.class)
public class AnnotationDrivenStaticEntityMockingControlTest {
@Test
public void testNoArgIntReturn() {
int expectedCount = 13;
Person.countPeople();
expectReturn(expectedCount);
playback();
assertEquals(expectedCount, Person.countPeople());
}
@Test(expected=PersistenceException.class)
public void testNoArgThrows() {
Person.countPeople();
expectThrow(new PersistenceException());
playback();
Person.countPeople();
}
@Test
public void testArgMethodMatches() {
long id = 13;
Person found = new Person();
Person.findPerson(id);
expectReturn(found);
playback();
assertEquals(found, Person.findPerson(id));
}
@Test
public void testLongSeriesOfCalls() {
long id1 = 13;
long id2 = 24;
Person found1 = new Person();
Person.findPerson(id1);
expectReturn(found1);
Person found2 = new Person();
Person.findPerson(id2);
expectReturn(found2);
Person.findPerson(id1);
expectReturn(found1);
Person.countPeople();
expectReturn(0);
playback();
assertEquals(found1, Person.findPerson(id1));
assertEquals(found2, Person.findPerson(id2));
assertEquals(found1, Person.findPerson(id1));
assertEquals(0, Person.countPeople());
}
// Note delegation is used when tests are invalid and should fail, as otherwise
// the failure will occur on the verify() method in the aspect after
// this method returns, failing the test case
@Test
public void testArgMethodNoMatchExpectReturn() {
try {
new Delegate().testArgMethodNoMatchExpectReturn();
fail();
} catch (IllegalArgumentException expected) {
}
}
@Test(expected=IllegalArgumentException.class)
public void testArgMethodNoMatchExpectThrow() {
new Delegate().testArgMethodNoMatchExpectThrow();
}
private void called(Person found, long id) {
assertEquals(found, Person.findPerson(id));
}
@Test
public void testReentrant() {
long id = 13;
Person found = new Person();
Person.findPerson(id);
expectReturn(found);
playback();
called(found, id);
}
@Test(expected=IllegalStateException.class)
public void testRejectUnexpectedCall() {
new Delegate().rejectUnexpectedCall();
}
@Test(expected=IllegalStateException.class)
public void testFailTooFewCalls() {
new Delegate().failTooFewCalls();
}
@Test
public void testEmpty() {
// Test that verification check doesn't blow up if no replay() call happened
}
@Test(expected=IllegalStateException.class)
public void testDoesntEverReplay() {
new Delegate().doesntEverReplay();
}
@Test(expected=IllegalStateException.class)
public void testDoesntEverSetReturn() {
new Delegate().doesntEverSetReturn();
}
}
@@ -0,0 +1,300 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.mock.staticmock;
import javax.persistence.PersistenceException;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl.*;
/**
* Tests for Spring's static entity mocking framework (i.e., @{@link MockStaticEntityMethods}
* and {@link AnnotationDrivenStaticEntityMockingControl}).
*
* @author Rod Johnson
* @author Ramnivas Laddad
* @author Sam Brannen
*/
@MockStaticEntityMethods
public class AnnotationDrivenStaticEntityMockingControlTests {
@Test
public void noArgumentMethodInvocationReturnsInt() {
int expectedCount = 13;
Person.countPeople();
expectReturn(expectedCount);
playback();
assertEquals(expectedCount, Person.countPeople());
}
@Test(expected = PersistenceException.class)
public void noArgumentMethodInvocationThrowsException() {
Person.countPeople();
expectThrow(new PersistenceException());
playback();
Person.countPeople();
}
@Test
public void methodArgumentsMatch() {
long id = 13;
Person found = new Person();
Person.findPerson(id);
expectReturn(found);
playback();
assertEquals(found, Person.findPerson(id));
}
@Test
public void longSeriesOfCalls() {
long id1 = 13;
long id2 = 24;
Person found1 = new Person();
Person.findPerson(id1);
expectReturn(found1);
Person found2 = new Person();
Person.findPerson(id2);
expectReturn(found2);
Person.findPerson(id1);
expectReturn(found1);
Person.countPeople();
expectReturn(0);
playback();
assertEquals(found1, Person.findPerson(id1));
assertEquals(found2, Person.findPerson(id2));
assertEquals(found1, Person.findPerson(id1));
assertEquals(0, Person.countPeople());
}
@Test(expected = IllegalArgumentException.class)
public void methodArgumentsDoNotMatchAndReturnsObject() {
long id = 13;
Person found = new Person();
Person.findPerson(id);
expectReturn(found);
playback();
assertEquals(found, Person.findPerson(id + 1));
}
@Test(expected = IllegalArgumentException.class)
public void methodArgumentsDoNotMatchAndThrowsException() {
long id = 13;
Person found = new Person();
Person.findPerson(id);
expectThrow(new PersistenceException());
playback();
assertEquals(found, Person.findPerson(id + 1));
}
@Test
public void reentrantCallToPrivateMethod() {
long id = 13;
Person found = new Person();
Person.findPerson(id);
expectReturn(found);
playback();
privateMethod(found, id);
}
private void privateMethod(Person found, long id) {
assertEquals(found, Person.findPerson(id));
}
@Test
public void reentrantCallToPublicMethod() {
final Long ID = 13L;
Person.findPerson(ID);
expectReturn(new Person());
playback();
try {
publicMethod();
fail("Should have thrown an IllegalStateException");
}
catch (IllegalStateException e) {
String snippet = "Calls have been recorded, but playback state was never reached.";
assertTrue("Exception message should contain [" + snippet + "]", e.getMessage().contains(snippet));
}
// Now to keep the mock for "this" method happy:
Person.findPerson(ID);
}
public void publicMethod() {
// At this point, since publicMethod() is a public method in a class
// annotated with @MockStaticEntityMethods, the current mock state is
// fresh. In other words, we are again in recording mode. As such, any
// call to a mocked method will return null. See the implementation of
// the <methodToMock() && cflowbelow(mockStaticsTestMethod())> around
// advice in AbstractMethodMockingControl for details.
assertNull(Person.findPerson(99L));
}
@Test(expected = IllegalStateException.class)
public void unexpectedCall() {
playback();
Person.countPeople();
}
@Test(expected = IllegalStateException.class)
public void tooFewCalls() {
long id = 13;
Person found = new Person();
Person.findPerson(id);
expectReturn(found);
Person.countPeople();
expectReturn(25);
playback();
assertEquals(found, Person.findPerson(id));
}
@Test
public void noExpectationsAndNoPlayback() {
// Ensure that mock verification doesn't blow up if playback() was not invoked and
// no expectations were set.
}
@Test
public void noExpectationsButWithPlayback() {
// Ensure that mock verification doesn't blow up if playback() was invoked but no
// expectations were set.
playback();
}
@Test(expected = IllegalStateException.class)
public void doesNotEnterPlaybackMode() {
Person.countPeople();
}
@Test(expected = IllegalStateException.class)
public void doesNotSetExpectedReturnValue() {
Person.countPeople();
playback();
}
/**
* Currently, the method mocking aspect will not verify the state of the
* expectations within the mock if a test method throws an exception.
*
* <p>The reason is that the {@code mockStaticsTestMethod()} advice in
* {@link AbstractMethodMockingControl} is declared as
* {@code after() returning} instead of simply {@code after()}.
*
* <p>If the aforementioned advice is changed to a generic "after" advice,
* this test method will fail with an {@link IllegalStateException} (thrown
* by the mock aspect) instead of the {@link UnsupportedOperationException}
* thrown by the test method itself.
*/
@Test(expected = UnsupportedOperationException.class)
public void mockVerificationDoesNotOccurIfTestFailsWithAnExpectedException() {
Person.countPeople();
playback();
// We intentionally do not execute any of the recorded method invocations in order
// to demonstrate that mock verification does not occur if an
// exception is thrown.
throw new UnsupportedOperationException();
}
@Test
public void resetMockWithoutVerficationAndStartOverWithoutRedeclaringExpectations() {
final Long ID = 13L;
Person.findPerson(ID);
expectReturn(new Person());
reset();
Person.findPerson(ID);
// Omit expectation.
playback();
try {
Person.findPerson(ID);
fail("Should have thrown an IllegalStateException");
}
catch (IllegalStateException e) {
String snippet = "Behavior of Call with signature";
assertTrue("Exception message should contain [" + snippet + "]", e.getMessage().contains(snippet));
}
}
@Test
public void resetMockWithoutVerificationAndStartOver() {
final Long ID = 13L;
Person found = new Person();
Person.findPerson(ID);
expectReturn(found);
reset();
// Intentionally use a different ID:
final long ID_2 = ID + 1;
Person.findPerson(ID_2);
expectReturn(found);
playback();
assertEquals(found, Person.findPerson(ID_2));
}
@Test
public void verifyResetAndStartOver() {
final Long ID_1 = 13L;
Person found1 = new Person();
Person.findPerson(ID_1);
expectReturn(found1);
playback();
assertEquals(found1, Person.findPerson(ID_1));
verify();
reset();
// Intentionally use a different ID:
final long ID_2 = ID_1 + 1;
Person found2 = new Person();
Person.findPerson(ID_2);
expectReturn(found2);
playback();
assertEquals(found2, Person.findPerson(ID_2));
}
@Test
public void verifyWithTooFewCalls() {
final Long ID = 13L;
Person found = new Person();
Person.findPerson(ID);
expectReturn(found);
Person.findPerson(ID);
expectReturn(found);
playback();
assertEquals(found, Person.findPerson(ID));
try {
verify();
fail("Should have thrown an IllegalStateException");
}
catch (IllegalStateException e) {
assertEquals("Expected 2 calls, but received 1", e.getMessage());
// Since verify() failed, we need to manually reset so that the test method
// does not fail.
reset();
}
}
}
@@ -1,92 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.mock.staticmock;
import static org.junit.Assert.assertEquals;
import java.rmi.RemoteException;
import javax.persistence.PersistenceException;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl;
import org.springframework.mock.staticmock.MockStaticEntityMethods;
//Used because verification failures occur after method returns,
//so we can't test for them in the test case itself
@MockStaticEntityMethods
@Ignore // This isn't meant for direct testing; rather it is driven from AnnotationDrivenStaticEntityMockingControl
public class Delegate {
@Test
public void testArgMethodNoMatchExpectReturn() {
long id = 13;
Person found = new Person();
Person.findPerson(id);
AnnotationDrivenStaticEntityMockingControl.expectReturn(found);
AnnotationDrivenStaticEntityMockingControl.playback();
assertEquals(found, Person.findPerson(id + 1));
}
@Test
public void testArgMethodNoMatchExpectThrow() {
long id = 13;
Person found = new Person();
Person.findPerson(id);
AnnotationDrivenStaticEntityMockingControl.expectThrow(new PersistenceException());
AnnotationDrivenStaticEntityMockingControl.playback();
assertEquals(found, Person.findPerson(id + 1));
}
@Test
public void failTooFewCalls() {
long id = 13;
Person found = new Person();
Person.findPerson(id);
AnnotationDrivenStaticEntityMockingControl.expectReturn(found);
Person.countPeople();
AnnotationDrivenStaticEntityMockingControl.expectReturn(25);
AnnotationDrivenStaticEntityMockingControl.playback();
assertEquals(found, Person.findPerson(id));
}
@Test
public void doesntEverReplay() {
Person.countPeople();
}
@Test
public void doesntEverSetReturn() {
Person.countPeople();
AnnotationDrivenStaticEntityMockingControl.playback();
}
@Test
public void rejectUnexpectedCall() {
AnnotationDrivenStaticEntityMockingControl.playback();
Person.countPeople();
}
@Test(expected=RemoteException.class)
public void testVerificationFailsEvenWhenTestFailsInExpectedManner() throws RemoteException {
Person.countPeople();
AnnotationDrivenStaticEntityMockingControl.playback();
// No calls to allow verification failure
throw new RemoteException();
}
}
@@ -0,0 +1,9 @@
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{HH:mm:ss,SSS} [%c] - %m%n
log4j.rootCategory=WARN, console
log4j.logger.org.springframework.beans=WARN
log4j.logger.org.springframework.binding=DEBUG
#log4j.logger.org.springframework=TRACE
@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- Appenders -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p: %c - %m%n" />
</layout>
</appender>
<logger name="org.springframework.beans">
<level value="warn" />
</logger>
<logger name="org.springframework.binding">
<level value="debug" />
</logger>
<!-- Root Logger -->
<root>
<priority value="warn" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -54,12 +54,14 @@ import org.springframework.core.io.DescriptiveResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.util.ObjectUtils;
/**
* A Groovy-based reader for Spring bean definitions: Like a Groovy builder,
* A Groovy-based reader for Spring bean definitions: like a Groovy builder,
* but more of a DSL for Spring configuration. Allows syntax like:
*
* <pre>import org.hibernate.SessionFactory
* <pre class="code">
* import org.hibernate.SessionFactory
* import org.apache.commons.dbcp.BasicDataSource
*
* def reader = new GroovyBeanDefinitionReader(myApplicationContext)
@@ -81,11 +83,12 @@ import org.springframework.core.io.support.ResourcePatternUtils;
* }
* }</pre>
*
* <p>You can also load resources containing beans defined as a Groovy script using
* <p>You can also load resources containing beans defined in a Groovy script using
* either the {@link #loadBeanDefinitions(org.springframework.core.io.Resource...)}
* or {@link #loadBeanDefinitions(String...)} method, with a script looking as follows:
*
* <pre>import org.hibernate.SessionFactory
* <pre class="code">
* import org.hibernate.SessionFactory
* import org.apache.commons.dbcp.BasicDataSource
*
* beans {
@@ -211,7 +214,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
Binding binding = new Binding() {
@Override
public void setVariable(String name, Object value) {
if (currentBeanDefinition !=null) {
if (currentBeanDefinition != null) {
applyPropertyToBeanDefinition(name, value);
}
else {
@@ -257,20 +260,19 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
}
/**
* Defines an inner bean definition
* @param type The bean type
* @param args The constructors arguments and closure configurer
* @return The bean definition
* Define an inner bean definition.
* @param type the bean type
* @param args the constructors arguments and closure configurer
* @return the bean definition
*/
public AbstractBeanDefinition bean(Class<?> type, Object...args) {
GroovyBeanDefinitionWrapper current = this.currentBeanDefinition;
try {
Closure callable = null;
Collection constructorArgs = null;
if (args != null && args.length > 0) {
if (!ObjectUtils.isEmpty(args)) {
int index = args.length;
Object lastArg = args[index-1];
if (lastArg instanceof Closure) {
callable = (Closure) lastArg;
index--;
@@ -292,7 +294,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
}
/**
* Defines an Spring namespace definition to use.
* Define a Spring namespace definition to use.
* @param definition the namespace definition
*/
public void xmlns(Map<String, String> definition) {
@@ -314,7 +316,8 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
}
/**
* Imports Spring bean definitions from either XML or Groovy sources into the current bean builder instance.
* Import Spring bean definitions from either XML or Groovy sources into the
* current bean builder instance.
* @param resourcePattern the resource pattern
*/
public void importBeans(String resourcePattern) throws IOException {
@@ -336,7 +339,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
/**
* This method overrides method invocation to create beans for each method name that
* takes a class argument
* takes a class argument.
*/
public Object invokeMethod(String name, Object arg) {
Object[] args = (Object[])arg;
@@ -407,11 +410,11 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
}
dp.apply();
}
deferredProperties.clear();
this.deferredProperties.clear();
}
/**
* When an methods argument is only a closure it is a set of bean definitions.
* When a method argument is only a closure it is a set of bean definitions.
* @param callable the closure argument
* @return this GroovyBeanDefinitionReader instance
*/
@@ -528,7 +531,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
}
/**
* Checks whether there are any {@link RuntimeBeanReference} inside the Map
* Checks whether there are any {@link RuntimeBeanReference}s inside the Map
* and converts it to a ManagedMap if necessary.
* @param map the original Map
* @return either the original map or a managed copy of it
@@ -550,8 +553,8 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
}
/**
* Checks whether there are any {@link RuntimeBeanReference} inside the Lis
* and converts it to a ManagedList if necessary.
* Checks whether there are any {@link RuntimeBeanReference}s inside the List
* and converts it to a ManagedList if necessary.
* @param list the original List
* @return either the original list or a managed copy of it
*/
@@ -612,10 +615,14 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
}
/**
* This method overrides property retrieval in the scope of the GroovyBeanDefinitionReader to either:
* a) Retrieve a variable from the bean builder's binding if it exists
* b) Retrieve a RuntimeBeanReference for a specific bean if it exists
* c) Otherwise just delegate to MetaClass.getProperty which will resolve properties from the GroovyBeanDefinitionReader itself
* This method overrides property retrieval in the scope of the
* GroovyBeanDefinitionReader to either:
* <ul>
* <li>Retrieve a variable from the bean builder's binding if it exists
* <li>Retrieve a RuntimeBeanReference for a specific bean if it exists
* <li>Otherwise just delegate to MetaClass.getProperty which will resolve
* properties from the GroovyBeanDefinitionReader itself
* </ul>
*/
public Object getProperty(String name) {
Binding binding = getBinding();
@@ -678,9 +685,10 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
/**
* This class is used to defer the adding of a property to a bean definition until later
* This is for a case where you assign a property to a list that may not contain bean references at
* that point of assignment, but may later hence it would need to be managed
* This class is used to defer the adding of a property to a bean definition
* until later. This is for a case where you assign a property to a list that
* may not contain bean references at that point of assignment, but may later;
* hence, it would need to be managed.
*/
private static class DeferredProperty {
@@ -703,7 +711,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
/**
* A RuntimeBeanReference that takes care of adding new properties to runtime references
* A RuntimeBeanReference that takes care of adding new properties to runtime references.
*/
private class GroovyRuntimeBeanReference extends RuntimeBeanReference implements GroovyObject {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,33 +20,36 @@ import java.beans.BeanInfo;
import java.beans.IntrospectionException;
/**
* Strategy for creating {@link BeanInfo} instances.
* Strategy interface for creating {@link BeanInfo} instances for Spring beans.
* Can be used to plug in custom bean property resolution strategies (e.g. for other
* languages on the JVM) or more efficient {@link BeanInfo} retrieval algorithms.
*
* <p>BeanInfoFactories are are instantiated by the {@link CachedIntrospectionResults},
* by using the {@link org.springframework.core.io.support.SpringFactoriesLoader} utility
* class.
* by using the {@link org.springframework.core.io.support.SpringFactoriesLoader}
* utility class.
*
* When a {@link BeanInfo} is to be created, the {@code CachedIntrospectionResults}
* will iterate through the discovered factories, calling {@link
* #getBeanInfo(Class)} on each one. If {@code null} is returned, the next factory will
* be queried. If none of the factories support the class, an standard {@link BeanInfo}
* is created as a default.
* will iterate through the discovered factories, calling {@link #getBeanInfo(Class)}
* on each one. If {@code null} is returned, the next factory will be queried.
* If none of the factories support the class, a standard {@link BeanInfo} will be
* created as a default.
*
* <p>Note that the {@link org.springframework.core.io.support.SpringFactoriesLoader}
* sorts the {@code BeanInfoFactory} instances by
* {@link org.springframework.core.annotation.Order @Order}, so that ones with
* a higher precedence come first.
* {@link org.springframework.core.annotation.Order @Order}, so that ones with a
* higher precedence come first.
*
* @author Arjen Poutsma
* @since 3.2
* @see CachedIntrospectionResults
* @see org.springframework.core.io.support.SpringFactoriesLoader
*/
public interface BeanInfoFactory {
/**
* Returns the bean info for the given class, if supported.
*
* Return the bean info for the given class, if supported.
* @param beanClass the bean class
* @return the bean info, or {@code null} if not the given class is not supported
* @return the BeanInfo, or {@code null} if the given class is not supported
* @throws IntrospectionException in case of exceptions
*/
BeanInfo getBeanInfo(Class<?> beanClass) throws IntrospectionException;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -49,11 +49,12 @@ public class BeanInstantiationException extends FatalBeanException {
this.beanClass = beanClass;
}
/**
* Return the offending bean class.
*/
public Class<?> getBeanClass() {
return beanClass;
return this.beanClass;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -57,7 +57,7 @@ public abstract class BeanUtils {
private static final Log logger = LogFactory.getLog(BeanUtils.class);
// using WeakHashMap as a Set
// Effectively using a WeakHashMap as a Set
private static final Map<Class<?>, Boolean> unknownEditorTypes =
Collections.synchronizedMap(new WeakHashMap<Class<?>, Boolean>());
@@ -127,7 +127,7 @@ public abstract class BeanUtils {
@SuppressWarnings("unchecked")
public static <T> T instantiateClass(Class<?> clazz, Class<T> assignableTo) throws BeanInstantiationException {
Assert.isAssignable(assignableTo, clazz);
return (T)instantiateClass(clazz);
return (T) instantiateClass(clazz);
}
/**
@@ -199,7 +199,7 @@ public abstract class BeanUtils {
* @return the Method object, or {@code null} if not found
* @see Class#getDeclaredMethod
*/
public static Method findDeclaredMethod(Class<?> clazz, String methodName, Class<?>[] paramTypes) {
public static Method findDeclaredMethod(Class<?> clazz, String methodName, Class<?>... paramTypes) {
try {
return clazz.getDeclaredMethod(methodName, paramTypes);
}
@@ -281,7 +281,7 @@ public abstract class BeanUtils {
}
else {
if (targetMethod.getParameterTypes().length == numParams) {
// Additional candidate with same length.
// Additional candidate with same length
numMethodsFoundWithCurrentMinimumArgs++;
}
}
@@ -317,10 +317,8 @@ public abstract class BeanUtils {
public static Method resolveSignature(String signature, Class<?> clazz) {
Assert.hasText(signature, "'signature' must not be empty");
Assert.notNull(clazz, "Class must not be null");
int firstParen = signature.indexOf("(");
int lastParen = signature.indexOf(")");
if (firstParen > -1 && lastParen == -1) {
throw new IllegalArgumentException("Invalid method signature '" + signature +
"': expected closing ')' for args list");
@@ -381,13 +379,28 @@ public abstract class BeanUtils {
* Find a JavaBeans {@code PropertyDescriptor} for the given method,
* with the method either being the read method or the write method for
* that bean property.
* @param method the method to find a corresponding PropertyDescriptor for
* @param method the method to find a corresponding PropertyDescriptor for,
* introspecting its declaring class
* @return the corresponding PropertyDescriptor, or {@code null} if none
* @throws BeansException if PropertyDescriptor lookup fails
*/
public static PropertyDescriptor findPropertyForMethod(Method method) throws BeansException {
return findPropertyForMethod(method, method.getDeclaringClass());
}
/**
* Find a JavaBeans {@code PropertyDescriptor} for the given method,
* with the method either being the read method or the write method for
* that bean property.
* @param method the method to find a corresponding PropertyDescriptor for
* @param clazz the (most specific) class to introspect for descriptors
* @return the corresponding PropertyDescriptor, or {@code null} if none
* @throws BeansException if PropertyDescriptor lookup fails
* @since 3.2.13
*/
public static PropertyDescriptor findPropertyForMethod(Method method, Class<?> clazz) throws BeansException {
Assert.notNull(method, "Method must not be null");
PropertyDescriptor[] pds = getPropertyDescriptors(method.getDeclaringClass());
PropertyDescriptor[] pds = getPropertyDescriptors(clazz);
for (PropertyDescriptor pd : pds) {
if (method.equals(pd.getReadMethod()) || method.equals(pd.getWriteMethod())) {
return pd;
@@ -455,7 +468,7 @@ public abstract class BeanUtils {
* @param beanClasses the classes to check against
* @return the property type, or {@code Object.class} as fallback
*/
public static Class<?> findPropertyType(String propertyName, Class<?>[] beanClasses) {
public static Class<?> findPropertyType(String propertyName, Class<?>... beanClasses) {
if (beanClasses != null) {
for (Class<?> beanClass : beanClasses) {
PropertyDescriptor pd = getPropertyDescriptor(beanClass, propertyName);
@@ -475,8 +488,7 @@ public abstract class BeanUtils {
*/
public static MethodParameter getWriteMethodParameter(PropertyDescriptor pd) {
if (pd instanceof GenericTypeAwarePropertyDescriptor) {
return new MethodParameter(
((GenericTypeAwarePropertyDescriptor) pd).getWriteMethodParameter());
return new MethodParameter(((GenericTypeAwarePropertyDescriptor) pd).getWriteMethodParameter());
}
else {
return new MethodParameter(pd.getWriteMethod(), 0);
@@ -528,7 +540,7 @@ public abstract class BeanUtils {
* @see BeanWrapper
*/
public static void copyProperties(Object source, Object target) throws BeansException {
copyProperties(source, target, null, null);
copyProperties(source, target, null, (String[]) null);
}
/**
@@ -545,10 +557,8 @@ public abstract class BeanUtils {
* @throws BeansException if the copying failed
* @see BeanWrapper
*/
public static void copyProperties(Object source, Object target, Class<?> editable)
throws BeansException {
copyProperties(source, target, editable, null);
public static void copyProperties(Object source, Object target, Class<?> editable) throws BeansException {
copyProperties(source, target, editable, (String[]) null);
}
/**
@@ -565,9 +575,7 @@ public abstract class BeanUtils {
* @throws BeansException if the copying failed
* @see BeanWrapper
*/
public static void copyProperties(Object source, Object target, String[] ignoreProperties)
throws BeansException {
public static void copyProperties(Object source, Object target, String... ignoreProperties) throws BeansException {
copyProperties(source, target, null, ignoreProperties);
}
@@ -583,7 +591,7 @@ public abstract class BeanUtils {
* @throws BeansException if the copying failed
* @see BeanWrapper
*/
private static void copyProperties(Object source, Object target, Class<?> editable, String[] ignoreProperties)
private static void copyProperties(Object source, Object target, Class<?> editable, String... ignoreProperties)
throws BeansException {
Assert.notNull(source, "Source must not be null");
@@ -598,27 +606,30 @@ public abstract class BeanUtils {
actualEditable = editable;
}
PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
List<String> ignoreList = (ignoreProperties != null) ? Arrays.asList(ignoreProperties) : null;
List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);
for (PropertyDescriptor targetPd : targetPds) {
if (targetPd.getWriteMethod() != null &&
(ignoreProperties == null || (!ignoreList.contains(targetPd.getName())))) {
Method writeMethod = targetPd.getWriteMethod();
if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
if (sourcePd != null && sourcePd.getReadMethod() != null) {
try {
Method readMethod = sourcePd.getReadMethod();
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
readMethod.setAccessible(true);
if (sourcePd != null) {
Method readMethod = sourcePd.getReadMethod();
if (readMethod != null &&
ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
try {
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
readMethod.setAccessible(true);
}
Object value = readMethod.invoke(source);
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
writeMethod.setAccessible(true);
}
writeMethod.invoke(target, value);
}
Object value = readMethod.invoke(source);
Method writeMethod = targetPd.getWriteMethod();
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
writeMethod.setAccessible(true);
catch (Throwable ex) {
throw new FatalBeanException(
"Could not copy property '" + targetPd.getName() + "' from source to target", ex);
}
writeMethod.invoke(target, value);
}
catch (Throwable ex) {
throw new FatalBeanException("Could not copy properties from source to target", ex);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -79,11 +79,13 @@ public interface BeanWrapper extends ConfigurablePropertyAccessor {
PropertyDescriptor getPropertyDescriptor(String propertyName) throws InvalidPropertyException;
/**
* Set whether this BeanWrapper should attempt to "auto-grow" a nested path that contains a null value.
* <p>If "true", a null path location will be populated with a default object value and traversed
* instead of resulting in a {@link NullValueInNestedPathException}. Turning this flag on also
* enables auto-growth of collection elements when accessing an out-of-bounds index.
* <p>Default is "false" on a plain BeanWrapper.
* Set whether this BeanWrapper should attempt to "auto-grow" a
* nested path that contains a {@code null} value.
* <p>If {@code true}, a {@code null} path location will be populated
* with a default object value and traversed instead of resulting in a
* {@link NullValueInNestedPathException}. Turning this flag on also enables
* auto-growth of collection elements when accessing an out-of-bounds index.
* <p>Default is {@code false} on a plain BeanWrapper.
*/
void setAutoGrowNestedPaths(boolean autoGrowNestedPaths);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,6 +37,7 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.CollectionFactory;
import org.springframework.core.GenericCollectionTypeResolver;
import org.springframework.core.convert.ConversionException;
@@ -397,7 +398,8 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
if (pd.getReadMethod() != null || pd.getWriteMethod() != null) {
return TypeDescriptor.nested(property(pd), tokens.keys.length);
}
} else {
}
else {
if (pd.getReadMethod() != null || pd.getWriteMethod() != null) {
return new TypeDescriptor(property(pd));
}
@@ -492,21 +494,22 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
public Object convertForProperty(Object value, String propertyName) throws TypeMismatchException {
CachedIntrospectionResults cachedIntrospectionResults = getCachedIntrospectionResults();
PropertyDescriptor pd = cachedIntrospectionResults.getPropertyDescriptor(propertyName);
TypeDescriptor td = cachedIntrospectionResults.getTypeDescriptor(pd);
if (pd == null) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"No property '" + propertyName + "' found");
}
TypeDescriptor td = cachedIntrospectionResults.getTypeDescriptor(pd);
if (td == null) {
td = new TypeDescriptor(property(pd));
cachedIntrospectionResults.putTypeDescriptor(pd, td);
cachedIntrospectionResults.addTypeDescriptor(pd, td);
}
return convertForProperty(propertyName, null, value, pd, td);
return convertForProperty(propertyName, null, value, td);
}
private Object convertForProperty(String propertyName, Object oldValue, Object newValue, PropertyDescriptor pd, TypeDescriptor td)
private Object convertForProperty(String propertyName, Object oldValue, Object newValue, TypeDescriptor td)
throws TypeMismatchException {
return convertIfNecessary(propertyName, oldValue, newValue, pd.getPropertyType(), td);
return convertIfNecessary(propertyName, oldValue, newValue, td.getType(), td);
}
private Property property(PropertyDescriptor pd) {
@@ -811,7 +814,8 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
Class<?> mapKeyType = GenericCollectionTypeResolver.getMapKeyReturnType(pd.getReadMethod(), i + 1);
// IMPORTANT: Do not pass full property name in here - property editors
// must not kick in for map keys but rather only for map values.
TypeDescriptor typeDescriptor = mapKeyType != null ? TypeDescriptor.valueOf(mapKeyType) : TypeDescriptor.valueOf(Object.class);
TypeDescriptor typeDescriptor = (mapKeyType != null ?
TypeDescriptor.valueOf(mapKeyType) : TypeDescriptor.valueOf(Object.class));
Object convertedMapKey = convertIfNecessary(null, null, key, mapKeyType, typeDescriptor);
value = map.get(convertedMapKey);
}
@@ -868,8 +872,9 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
}
}
private void growCollectionIfNecessary(Collection<Object> collection, int index,
String name, PropertyDescriptor pd, int nestingLevel) {
private void growCollectionIfNecessary(Collection<Object> collection, int index, String name,
PropertyDescriptor pd, int nestingLevel) {
if (!this.autoGrowNestedPaths) {
return;
}
@@ -1112,7 +1117,8 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
}
}
}
valueToApply = convertForProperty(propertyName, oldValue, originalValue, pd, new TypeDescriptor(property(pd)));
valueToApply = convertForProperty(
propertyName, oldValue, originalValue, new TypeDescriptor(property(pd)));
}
pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,8 +21,7 @@ import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.lang.ref.SoftReference;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
@@ -30,9 +29,12 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.SpringProperties;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.util.ClassUtils;
@@ -51,6 +53,18 @@ import org.springframework.util.StringUtils;
* implements the factory design pattern, using a private constructor and
* a static {@link #forClass(Class)} factory method to obtain instances.
*
* <p>Note that for caching to work effectively, some preconditions need to be met:
* Prefer an arrangement where the Spring jars live in the same ClassLoader as the
* application classes, which allows for clean caching along with the application's
* lifecycle in any case. For a web application, consider declaring a local
* {@link org.springframework.web.util.IntrospectorCleanupListener} in {@code web.xml}
* in case of a multi-ClassLoader layout, which will allow for effective caching as well.
*
* <p>In case of a non-clean ClassLoader arrangement without a cleanup listener having
* been set up, this class will fall back to a weak-reference-based caching model that
* recreates much-requested entries every time the garbage collector removed them. In
* such a scenario, consider the {@link #IGNORE_BEANINFO_PROPERTY_NAME} system property.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 05 May 2001
@@ -60,11 +74,34 @@ import org.springframework.util.StringUtils;
*/
public class CachedIntrospectionResults {
private static final Log logger = LogFactory.getLog(CachedIntrospectionResults.class);
/**
* System property that instructs Spring to use the {@link Introspector#IGNORE_ALL_BEANINFO}
* mode when calling the JavaBeans {@link Introspector}: "spring.beaninfo.ignore", with a
* value of "true" skipping the search for {@code BeanInfo} classes (typically for scenarios
* where no such classes are being defined for beans in the application in the first place).
* <p>The default is "false", considering all {@code BeanInfo} metadata classes, like for
* standard {@link Introspector#getBeanInfo(Class)} calls. Consider switching this flag to
* "true" if you experience repeated ClassLoader access for non-existing {@code BeanInfo}
* classes, in case such access is expensive on startup or on lazy loading.
* <p>Note that such an effect may also indicate a scenario where caching doesn't work
* effectively: Prefer an arrangement where the Spring jars live in the same ClassLoader
* as the application classes, which allows for clean caching along with the application's
* lifecycle in any case. For a web application, consider declaring a local
* {@link org.springframework.web.util.IntrospectorCleanupListener} in {@code web.xml}
* in case of a multi-ClassLoader layout, which will allow for effective caching as well.
* @see Introspector#getBeanInfo(Class, int)
*/
public static final String IGNORE_BEANINFO_PROPERTY_NAME = "spring.beaninfo.ignore";
private static final boolean shouldIntrospectorIgnoreBeaninfoClasses =
SpringProperties.getFlag(IGNORE_BEANINFO_PROPERTY_NAME);
/** Stores the BeanInfoFactory instances */
private static List<BeanInfoFactory> beanInfoFactories =
SpringFactoriesLoader.loadFactories(BeanInfoFactory.class, CachedIntrospectionResults.class.getClassLoader());
private static List<BeanInfoFactory> beanInfoFactories = SpringFactoriesLoader.loadFactories(
BeanInfoFactory.class, CachedIntrospectionResults.class.getClassLoader());
private static final Log logger = LogFactory.getLog(CachedIntrospectionResults.class);
/**
* Set of ClassLoaders that this CachedIntrospectionResults class will always
@@ -159,7 +196,7 @@ public class CachedIntrospectionResults {
}
results = new CachedIntrospectionResults(beanClass);
synchronized (classCache) {
classCache.put(beanClass, new WeakReference<CachedIntrospectionResults>(results));
classCache.put(beanClass, new SoftReference<CachedIntrospectionResults>(results));
}
}
}
@@ -180,8 +217,8 @@ public class CachedIntrospectionResults {
synchronized (acceptedClassLoaders) {
acceptedLoaderArray = acceptedClassLoaders.toArray(new ClassLoader[acceptedClassLoaders.size()]);
}
for (ClassLoader registeredLoader : acceptedLoaderArray) {
if (isUnderneathClassLoader(classLoader, registeredLoader)) {
for (ClassLoader acceptedLoader : acceptedLoaderArray) {
if (isUnderneathClassLoader(classLoader, acceptedLoader)) {
return true;
}
}
@@ -242,21 +279,12 @@ public class CachedIntrospectionResults {
}
if (beanInfo == null) {
// If none of the factories supported the class, fall back to the default
beanInfo = Introspector.getBeanInfo(beanClass);
beanInfo = (shouldIntrospectorIgnoreBeaninfoClasses ?
Introspector.getBeanInfo(beanClass, Introspector.IGNORE_ALL_BEANINFO) :
Introspector.getBeanInfo(beanClass));
}
this.beanInfo = beanInfo;
// Immediately remove class from Introspector cache, to allow for proper
// garbage collection on class loader shutdown - we cache it here anyway,
// in a GC-friendly manner. In contrast to CachedIntrospectionResults,
// Introspector does not use WeakReferences as values of its WeakHashMap!
Class<?> classToFlush = beanClass;
do {
Introspector.flushFromCaches(classToFlush);
classToFlush = classToFlush.getSuperclass();
}
while (classToFlush != null);
if (logger.isTraceEnabled()) {
logger.trace("Caching PropertyDescriptors for class [" + beanClass.getName() + "]");
}
@@ -265,8 +293,9 @@ public class CachedIntrospectionResults {
// This call is slow so we do it once.
PropertyDescriptor[] pds = this.beanInfo.getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
if (Class.class.equals(beanClass) && "classLoader".equals(pd.getName())) {
// Ignore Class.getClassLoader() method - nobody needs to bind to that
if (Class.class.equals(beanClass) &&
("classLoader".equals(pd.getName()) || "protectionDomain".equals(pd.getName()))) {
// Ignore Class.getClassLoader() and getProtectionDomain() methods - nobody needs to bind to those
continue;
}
if (logger.isTraceEnabled()) {
@@ -279,7 +308,7 @@ public class CachedIntrospectionResults {
this.propertyDescriptorCache.put(pd.getName(), pd);
}
this.typeDescriptorCache = new HashMap<PropertyDescriptor, TypeDescriptor>();
this.typeDescriptorCache = new ConcurrentHashMap<PropertyDescriptor, TypeDescriptor>();
}
catch (IntrospectionException ex) {
throw new FatalBeanException("Failed to obtain BeanInfo for class [" + beanClass.getName() + "]", ex);
@@ -328,12 +357,12 @@ public class CachedIntrospectionResults {
}
}
void addTypeDescriptor(PropertyDescriptor pd, TypeDescriptor td) {
this.typeDescriptorCache.put(pd, td);
}
TypeDescriptor getTypeDescriptor(PropertyDescriptor pd) {
return this.typeDescriptorCache.get(pd);
}
void putTypeDescriptor(PropertyDescriptor pd, TypeDescriptor td) {
this.typeDescriptorCache.put(pd, td);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,6 +35,9 @@ import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import static org.springframework.beans.PropertyDescriptorUtils.*;
/**
@@ -73,6 +76,8 @@ import static org.springframework.beans.PropertyDescriptorUtils.*;
*/
class ExtendedBeanInfo implements BeanInfo {
private static final Log logger = LogFactory.getLog(ExtendedBeanInfo.class);
private final BeanInfo delegate;
private final Set<PropertyDescriptor> propertyDescriptors =
@@ -94,14 +99,30 @@ class ExtendedBeanInfo implements BeanInfo {
public ExtendedBeanInfo(BeanInfo delegate) throws IntrospectionException {
this.delegate = delegate;
for (PropertyDescriptor pd : delegate.getPropertyDescriptors()) {
this.propertyDescriptors.add(pd instanceof IndexedPropertyDescriptor ?
new SimpleIndexedPropertyDescriptor((IndexedPropertyDescriptor) pd) :
new SimplePropertyDescriptor(pd));
try {
this.propertyDescriptors.add(pd instanceof IndexedPropertyDescriptor ?
new SimpleIndexedPropertyDescriptor((IndexedPropertyDescriptor) pd) :
new SimplePropertyDescriptor(pd));
}
catch (IntrospectionException ex) {
// Probably simply a method that wasn't meant to follow the JavaBeans pattern...
if (logger.isDebugEnabled()) {
logger.debug("Ignoring invalid bean property '" + pd.getName() + "': " + ex.getMessage());
}
}
}
MethodDescriptor[] methodDescriptors = delegate.getMethodDescriptors();
if (methodDescriptors != null) {
for (Method method : findCandidateWriteMethods(methodDescriptors)) {
handleCandidateWriteMethod(method);
try {
handleCandidateWriteMethod(method);
}
catch (IntrospectionException ex) {
// We're only trying to find candidates, can easily ignore extra ones here...
if (logger.isDebugEnabled()) {
logger.debug("Ignoring candidate write method [" + method + "]: " + ex.getMessage());
}
}
}
}
}
@@ -115,7 +136,7 @@ class ExtendedBeanInfo implements BeanInfo {
matches.add(method);
}
}
// sort non-void returning write methods to guard against the ill effects of
// Sort non-void returning write methods to guard against the ill effects of
// non-deterministic sorting of methods returned from Class#getDeclaredMethods
// under JDK 7. See http://bugs.sun.com/view_bug.do?bug_id=7023180
Collections.sort(matches, new Comparator<Method>() {
@@ -131,15 +152,15 @@ class ExtendedBeanInfo implements BeanInfo {
String methodName = method.getName();
Class<?>[] parameterTypes = method.getParameterTypes();
int nParams = parameterTypes.length;
return methodName.length() > 3 && methodName.startsWith("set") && Modifier.isPublic(method.getModifiers()) &&
return (methodName.length() > 3 && methodName.startsWith("set") && Modifier.isPublic(method.getModifiers()) &&
(!void.class.isAssignableFrom(method.getReturnType()) || Modifier.isStatic(method.getModifiers())) &&
(nParams == 1 || (nParams == 2 && parameterTypes[0].equals(int.class)));
(nParams == 1 || (nParams == 2 && parameterTypes[0].equals(int.class))));
}
private void handleCandidateWriteMethod(Method method) throws IntrospectionException {
int nParams = method.getParameterTypes().length;
String propertyName = propertyNameFor(method);
Class<?> propertyType = method.getParameterTypes()[nParams-1];
Class<?> propertyType = method.getParameterTypes()[nParams - 1];
PropertyDescriptor existingPd = findExistingPropertyDescriptor(propertyName, propertyType);
if (nParams == 1) {
if (existingPd == null) {
@@ -209,37 +230,37 @@ class ExtendedBeanInfo implements BeanInfo {
@Override
public BeanInfo[] getAdditionalBeanInfo() {
return delegate.getAdditionalBeanInfo();
return this.delegate.getAdditionalBeanInfo();
}
@Override
public BeanDescriptor getBeanDescriptor() {
return delegate.getBeanDescriptor();
return this.delegate.getBeanDescriptor();
}
@Override
public int getDefaultEventIndex() {
return delegate.getDefaultEventIndex();
return this.delegate.getDefaultEventIndex();
}
@Override
public int getDefaultPropertyIndex() {
return delegate.getDefaultPropertyIndex();
return this.delegate.getDefaultPropertyIndex();
}
@Override
public EventSetDescriptor[] getEventSetDescriptors() {
return delegate.getEventSetDescriptors();
return this.delegate.getEventSetDescriptors();
}
@Override
public Image getIcon(int iconKind) {
return delegate.getIcon(iconKind);
return this.delegate.getIcon(iconKind);
}
@Override
public MethodDescriptor[] getMethodDescriptors() {
return delegate.getMethodDescriptors();
return this.delegate.getMethodDescriptors();
}
}
@@ -293,7 +314,7 @@ class SimplePropertyDescriptor extends PropertyDescriptor {
this.propertyType = findPropertyType(this.readMethod, this.writeMethod);
}
catch (IntrospectionException ex) {
// ignore, as does PropertyDescriptor#getPropertyType
// Ignore, as does PropertyDescriptor#getPropertyType
}
}
return this.propertyType;
@@ -383,7 +404,7 @@ class SimpleIndexedPropertyDescriptor extends IndexedPropertyDescriptor {
this.propertyType = findPropertyType(this.readMethod, this.writeMethod);
}
catch (IntrospectionException ex) {
// ignore, as does IndexedPropertyDescriptor#getPropertyType
// Ignore, as does IndexedPropertyDescriptor#getPropertyType
}
}
return this.propertyType;
@@ -417,7 +438,7 @@ class SimpleIndexedPropertyDescriptor extends IndexedPropertyDescriptor {
getName(), getPropertyType(), this.indexedReadMethod, this.indexedWriteMethod);
}
catch (IntrospectionException ex) {
// ignore, as does IndexedPropertyDescriptor#getIndexedPropertyType
// Ignore, as does IndexedPropertyDescriptor#getIndexedPropertyType
}
}
return this.indexedPropertyType;
@@ -437,24 +458,24 @@ class SimpleIndexedPropertyDescriptor extends IndexedPropertyDescriptor {
* See java.beans.IndexedPropertyDescriptor#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (obj != null && obj instanceof IndexedPropertyDescriptor) {
IndexedPropertyDescriptor other = (IndexedPropertyDescriptor) obj;
if (!compareMethods(getIndexedReadMethod(), other.getIndexedReadMethod())) {
return false;
}
if (!compareMethods(getIndexedWriteMethod(), other.getIndexedWriteMethod())) {
return false;
}
if (getIndexedPropertyType() != other.getIndexedPropertyType()) {
return false;
}
return PropertyDescriptorUtils.equals(this, obj);
if (!(other instanceof IndexedPropertyDescriptor)) {
return false;
}
return false;
IndexedPropertyDescriptor otherPd = (IndexedPropertyDescriptor) other;
if (!compareMethods(getIndexedReadMethod(), otherPd.getIndexedReadMethod())) {
return false;
}
if (!compareMethods(getIndexedWriteMethod(), otherPd.getIndexedWriteMethod())) {
return false;
}
if (getIndexedPropertyType() != otherPd.getIndexedPropertyType()) {
return false;
}
return PropertyDescriptorUtils.equals(this, other);
}
@Override
@@ -482,14 +503,14 @@ class PropertyDescriptorUtils {
target.setShortDescription(source.getShortDescription());
target.setDisplayName(source.getDisplayName());
// copy all attributes (emulating behavior of private FeatureDescriptor#addTable)
// Copy all attributes (emulating behavior of private FeatureDescriptor#addTable)
Enumeration<String> keys = source.attributeNames();
while (keys.hasMoreElements()) {
String key = keys.nextElement();
target.setValue(key, source.getValue(key));
}
// see java.beans.PropertyDescriptor#PropertyDescriptor(PropertyDescriptor)
// See java.beans.PropertyDescriptor#PropertyDescriptor(PropertyDescriptor)
target.setPropertyEditorClass(source.getPropertyEditorClass());
target.setBound(source.isBound());
target.setConstrained(source.isConstrained());
@@ -503,24 +524,34 @@ class PropertyDescriptorUtils {
if (readMethod != null) {
Class<?>[] params = readMethod.getParameterTypes();
if (params.length != 0) {
throw new IntrospectionException("bad read method arg count: " + readMethod);
throw new IntrospectionException("Bad read method arg count: " + readMethod);
}
propertyType = readMethod.getReturnType();
if (propertyType == Void.TYPE) {
throw new IntrospectionException("read method "
+ readMethod.getName() + " returns void");
throw new IntrospectionException("Read method returns void: " + readMethod);
}
}
if (writeMethod != null) {
Class<?> params[] = writeMethod.getParameterTypes();
if (params.length != 1) {
throw new IntrospectionException("bad write method arg count: " + writeMethod);
throw new IntrospectionException("Bad write method arg count: " + writeMethod);
}
if (propertyType != null
&& !params[0].isAssignableFrom(propertyType)) {
throw new IntrospectionException("type mismatch between read and write methods");
if (propertyType != null) {
if (propertyType.isAssignableFrom(params[0])) {
// Write method's property type potentially more specific
propertyType = params[0];
}
else if (params[0].isAssignableFrom(propertyType)) {
// Proceed with read method's property type
}
else {
throw new IntrospectionException(
"Type mismatch between read and write methods: " + readMethod + " - " + writeMethod);
}
}
else {
propertyType = params[0];
}
propertyType = params[0];
}
return propertyType;
}
@@ -532,44 +563,48 @@ class PropertyDescriptorUtils {
Method indexedReadMethod, Method indexedWriteMethod) throws IntrospectionException {
Class<?> indexedPropertyType = null;
if (indexedReadMethod != null) {
Class<?> params[] = indexedReadMethod.getParameterTypes();
if (params.length != 1) {
throw new IntrospectionException(
"bad indexed read method arg count");
throw new IntrospectionException("Bad indexed read method arg count: " + indexedReadMethod);
}
if (params[0] != Integer.TYPE) {
throw new IntrospectionException(
"non int index to indexed read method");
throw new IntrospectionException("Non int index to indexed read method: " + indexedReadMethod);
}
indexedPropertyType = indexedReadMethod.getReturnType();
if (indexedPropertyType == Void.TYPE) {
throw new IntrospectionException(
"indexed read method returns void");
throw new IntrospectionException("Indexed read method returns void: " + indexedReadMethod);
}
}
if (indexedWriteMethod != null) {
Class<?> params[] = indexedWriteMethod.getParameterTypes();
if (params.length != 2) {
throw new IntrospectionException(
"bad indexed write method arg count");
throw new IntrospectionException("Bad indexed write method arg count: " + indexedWriteMethod);
}
if (params[0] != Integer.TYPE) {
throw new IntrospectionException(
"non int index to indexed write method");
throw new IntrospectionException("Non int index to indexed write method: " + indexedWriteMethod);
}
if (indexedPropertyType != null && indexedPropertyType != params[1]) {
throw new IntrospectionException(
"type mismatch between indexed read and indexed write methods: " + name);
if (indexedPropertyType != null) {
if (indexedPropertyType.isAssignableFrom(params[1])) {
// Write method's property type potentially more specific
indexedPropertyType = params[1];
}
else if (params[1].isAssignableFrom(indexedPropertyType)) {
// Proceed with read method's property type
}
else {
throw new IntrospectionException("Type mismatch between indexed read and write methods: " +
indexedReadMethod + " - " + indexedWriteMethod);
}
}
else {
indexedPropertyType = params[1];
}
indexedPropertyType = params[1];
}
if (propertyType != null
&& (!propertyType.isArray() ||
propertyType.getComponentType() != indexedPropertyType)) {
throw new IntrospectionException(
"type mismatch between indexed and non-indexed methods: " + name);
if (propertyType != null && (!propertyType.isArray() ||
propertyType.getComponentType() != indexedPropertyType)) {
throw new IntrospectionException("Type mismatch between indexed and non-indexed methods: " +
indexedReadMethod + " - " + indexedWriteMethod);
}
return indexedPropertyType;
}
@@ -581,28 +616,23 @@ class PropertyDescriptorUtils {
* editor and flags are equivalent.
* @see PropertyDescriptor#equals(Object)
*/
public static boolean equals(PropertyDescriptor pd1, Object obj) {
if (pd1 == obj) {
public static boolean equals(PropertyDescriptor pd, Object other) {
if (pd == other) {
return true;
}
if (obj != null && obj instanceof PropertyDescriptor) {
PropertyDescriptor pd2 = (PropertyDescriptor) obj;
if (!compareMethods(pd1.getReadMethod(), pd2.getReadMethod())) {
return false;
}
if (!compareMethods(pd1.getWriteMethod(), pd2.getWriteMethod())) {
return false;
}
if (pd1.getPropertyType() == pd2.getPropertyType()
&& pd1.getPropertyEditorClass() == pd2.getPropertyEditorClass()
&& pd1.isBound() == pd2.isBound()
&& pd1.isConstrained() == pd2.isConstrained()) {
return true;
}
if (!(other instanceof PropertyDescriptor)) {
return false;
}
return false;
PropertyDescriptor otherPd = (PropertyDescriptor) other;
if (!compareMethods(pd.getReadMethod(), otherPd.getReadMethod())) {
return false;
}
if (!compareMethods(pd.getWriteMethod(), otherPd.getWriteMethod())) {
return false;
}
return (pd.getPropertyType() == otherPd.getPropertyType() &&
pd.getPropertyEditorClass() == otherPd.getPropertyEditorClass() &&
pd.isBound() == otherPd.isBound() && pd.isConstrained() == otherPd.isConstrained());
}
/*
@@ -612,7 +642,7 @@ class PropertyDescriptorUtils {
if ((a == null) != (b == null)) {
return false;
}
if (a != null && b != null) {
if (a != null) {
if (!a.equals(b)) {
return false;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,8 +25,8 @@ import org.springframework.core.Ordered;
/**
* {@link BeanInfoFactory} implementation that evaluates whether bean classes have
* "non-standard" JavaBeans setter methods and are thus candidates for introspection by
* Spring's {@link ExtendedBeanInfo}.
* "non-standard" JavaBeans setter methods and are thus candidates for introspection
* by Spring's (package-visible) {@code ExtendedBeanInfo} implementation.
*
* <p>Ordered at {@link Ordered#LOWEST_PRECEDENCE} to allow other user-defined
* {@link BeanInfoFactory} types to take precedence.
@@ -34,21 +34,21 @@ import org.springframework.core.Ordered;
* @author Chris Beams
* @since 3.2
* @see BeanInfoFactory
* @see CachedIntrospectionResults
*/
public class ExtendedBeanInfoFactory implements Ordered, BeanInfoFactory {
public class ExtendedBeanInfoFactory implements BeanInfoFactory, Ordered {
/**
* Return a new {@link ExtendedBeanInfo} for the given bean class.
* Return an {@link ExtendedBeanInfo} for the given bean class, if applicable.
*/
@Override
public BeanInfo getBeanInfo(Class<?> beanClass) throws IntrospectionException {
return supports(beanClass) ?
new ExtendedBeanInfo(Introspector.getBeanInfo(beanClass)) : null;
return (supports(beanClass) ? new ExtendedBeanInfo(Introspector.getBeanInfo(beanClass)) : null);
}
/**
* Return whether the given bean class declares or inherits any non-void returning
* JavaBeans or <em>indexed property</em> setter methods.
* Return whether the given bean class declares or inherits any non-void
* returning bean property or indexed property setter methods.
*/
private boolean supports(Class<?> beanClass) {
for (Method method : beanClass.getMethods()) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@ import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.GenericTypeResolver;
import org.springframework.core.MethodParameter;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
@@ -38,7 +39,7 @@ import org.springframework.util.StringUtils;
* @author Juergen Hoeller
* @since 2.5.2
*/
class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
final class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
private final Class<?> beanClass;
@@ -46,13 +47,13 @@ class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
private final Method writeMethod;
private final Class<?> propertyEditorClass;
private volatile Set<Method> ambiguousWriteMethods;
private MethodParameter writeMethodParameter;
private Class<?> propertyType;
private MethodParameter writeMethodParameter;
private final Class<?> propertyEditorClass;
public GenericTypeAwarePropertyDescriptor(Class<?> beanClass, String propertyName,
@@ -60,8 +61,11 @@ class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
throws IntrospectionException {
super(propertyName, null, null);
if (beanClass == null) {
throw new IntrospectionException("Bean class must not be null");
}
this.beanClass = beanClass;
this.propertyEditorClass = propertyEditorClass;
Method readMethodToUse = BridgeMethodResolver.findBridgedMethod(readMethod);
Method writeMethodToUse = BridgeMethodResolver.findBridgedMethod(writeMethod);
@@ -93,8 +97,11 @@ class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
this.ambiguousWriteMethods = ambiguousCandidates;
}
}
this.propertyEditorClass = propertyEditorClass;
}
public Class<?> getBeanClass() {
return this.beanClass;
}
@@ -120,9 +127,15 @@ class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
return this.writeMethod;
}
@Override
public Class<?> getPropertyEditorClass() {
return this.propertyEditorClass;
public synchronized MethodParameter getWriteMethodParameter() {
if (this.writeMethod == null) {
return null;
}
if (this.writeMethodParameter == null) {
this.writeMethodParameter = new MethodParameter(this.writeMethod, 0);
GenericTypeResolver.resolveParameterType(this.writeMethodParameter, this.beanClass);
}
return this.writeMethodParameter;
}
@Override
@@ -144,15 +157,34 @@ class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
return this.propertyType;
}
public synchronized MethodParameter getWriteMethodParameter() {
if (this.writeMethod == null) {
return null;
@Override
public Class<?> getPropertyEditorClass() {
return this.propertyEditorClass;
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (this.writeMethodParameter == null) {
this.writeMethodParameter = new MethodParameter(this.writeMethod, 0);
GenericTypeResolver.resolveParameterType(this.writeMethodParameter, this.beanClass);
if (!(other instanceof GenericTypeAwarePropertyDescriptor)) {
return false;
}
return this.writeMethodParameter;
GenericTypeAwarePropertyDescriptor otherPd = (GenericTypeAwarePropertyDescriptor) other;
return (getBeanClass().equals(otherPd.getBeanClass()) &&
ObjectUtils.nullSafeEquals(getReadMethod(), otherPd.getReadMethod()) &&
ObjectUtils.nullSafeEquals(getWriteMethod(), otherPd.getWriteMethod()) &&
ObjectUtils.nullSafeEquals(getPropertyEditorClass(), otherPd.getPropertyEditorClass()) &&
isBound() == otherPd.isBound() && isConstrained() == otherPd.isConstrained());
}
@Override
public int hashCode() {
int hashCode = getBeanClass().hashCode();
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(getReadMethod());
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(getWriteMethod());
return hashCode;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -263,6 +263,7 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
* Get the raw property value, if any.
* @param propertyName the name to search for
* @return the raw property value, or {@code null}
* @since 4.0
* @see #getPropertyValue(String)
* @see PropertyValue#getValue()
*/
@@ -320,6 +321,16 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
this.processedProperties.add(propertyName);
}
/**
* Clear the "processed" registration of the given property, if any.
* @since 3.2.13
*/
public void clearProcessedProperty(String propertyName) {
if (this.processedProperties != null) {
this.processedProperties.remove(propertyName);
}
}
/**
* Mark this holder as containing converted values only
* (i.e. no runtime resolution needed anymore).
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,4 +47,16 @@ public class NotReadablePropertyException extends InvalidPropertyException {
super(beanClass, propertyName, msg);
}
/**
* Create a new NotReadablePropertyException.
* @param beanClass the offending bean class
* @param propertyName the offending property
* @param msg the detail message
* @param cause the root cause
* @since 4.0.9
*/
public NotReadablePropertyException(Class<?> beanClass, String propertyName, String msg, Throwable cause) {
super(beanClass, propertyName, msg, cause);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -89,7 +89,7 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
static {
try {
zoneIdClass = PropertyEditorRegistrySupport.class.getClassLoader().loadClass("java.time.ZoneId");
zoneIdClass = ClassUtils.forName("java.time.ZoneId", PropertyEditorRegistrySupport.class.getClassLoader());
}
catch (ClassNotFoundException ex) {
// Java 8 ZoneId class not available
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -172,7 +172,8 @@ final class PropertyMatches {
char t_j = s2.charAt(j - 1);
if (s_i == t_j) {
cost = 0;
} else {
}
else {
cost = 1;
}
d[i][j] = Math.min(Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1),
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -289,19 +289,19 @@ class TypeConverterDelegate {
if (index > - 1) {
String enumType = trimmedValue.substring(0, index);
String fieldName = trimmedValue.substring(index + 1);
ClassLoader loader = this.targetObject.getClass().getClassLoader();
ClassLoader cl = this.targetObject.getClass().getClassLoader();
try {
Class<?> enumValueType = loader.loadClass(enumType);
Class<?> enumValueType = ClassUtils.forName(enumType, cl);
Field enumField = enumValueType.getField(fieldName);
convertedValue = enumField.get(null);
}
catch (ClassNotFoundException ex) {
if(logger.isTraceEnabled()) {
logger.trace("Enum class [" + enumType + "] cannot be loaded from [" + loader + "]", ex);
if (logger.isTraceEnabled()) {
logger.trace("Enum class [" + enumType + "] cannot be loaded", ex);
}
}
catch (Throwable ex) {
if(logger.isTraceEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Field [" + fieldName + "] isn't an enum value for type [" + enumType + "]", ex);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -170,8 +170,7 @@ public interface BeanFactory {
* <p>Allows for specifying explicit constructor arguments / factory method arguments,
* overriding the specified default arguments (if any) in the bean definition.
* @param name the name of the bean to retrieve
* @param args arguments to use if creating a prototype using explicit arguments to a
* static factory method. It is invalid to use a non-null args value in any other case.
* @param args arguments to use if creating a prototype using explicit arguments
* @return an instance of the bean
* @throws NoSuchBeanDefinitionException if there is no such bean definition
* @throws BeanDefinitionStoreException if arguments have been given but
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,21 +20,23 @@ import org.springframework.beans.BeansException;
import org.springframework.util.StringUtils;
/**
* Exception thrown when a {@code BeanFactory} is asked for a bean instance
* for which it cannot find a definition.
* Exception thrown when a {@code BeanFactory} is asked for a bean instance for which it
* cannot find a definition. This may point to a non-existing bean, a non-unique bean,
* or a manually registered singleton instance without an associated bean definition.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @see BeanFactory#getBean(String)
* @see BeanFactory#getBean(Class)
* @see NoUniqueBeanDefinitionException
*/
@SuppressWarnings("serial")
public class NoSuchBeanDefinitionException extends BeansException {
/** Name of the missing bean. */
/** Name of the missing bean */
private String beanName;
/** Required type of the missing bean. */
/** Required type of the missing bean */
private Class<?> beanType;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@ package org.springframework.beans.factory.access.el;
import java.beans.FeatureDescriptor;
import java.util.Iterator;
import javax.el.ELContext;
import javax.el.ELException;
import javax.el.ELResolver;
@@ -78,8 +77,14 @@ public abstract class SpringBeanELResolver extends ELResolver {
String beanName = property.toString();
BeanFactory bf = getBeanFactory(elContext);
if (bf.containsBean(beanName)) {
throw new PropertyNotWritableException(
"Variable '" + beanName + "' refers to a Spring bean which by definition is not writable");
if (value == bf.getBean(beanName)) {
// Setting the bean reference to the same value is alright - can simply be ignored...
elContext.setPropertyResolved(true);
}
else {
throw new PropertyNotWritableException(
"Variable '" + beanName + "' refers to a Spring bean which by definition is not writable");
}
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -135,9 +135,9 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
public AutowiredAnnotationBeanPostProcessor() {
this.autowiredAnnotationTypes.add(Autowired.class);
this.autowiredAnnotationTypes.add(Value.class);
ClassLoader cl = AutowiredAnnotationBeanPostProcessor.class.getClassLoader();
try {
this.autowiredAnnotationTypes.add((Class<? extends Annotation>) cl.loadClass("javax.inject.Inject"));
this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
logger.info("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
}
catch (ClassNotFoundException ex) {
@@ -218,7 +218,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (beanType != null) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType);
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
}
@@ -236,24 +236,25 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
Constructor<?> requiredConstructor = null;
Constructor<?> defaultConstructor = null;
for (Constructor<?> candidate : rawCandidates) {
AnnotationAttributes annotation = findAutowiredAnnotation(candidate);
if (annotation != null) {
AnnotationAttributes ann = findAutowiredAnnotation(candidate);
if (ann != null) {
if (requiredConstructor != null) {
throw new BeanCreationException("Invalid autowire-marked constructor: " + candidate +
". Found another constructor with 'required' Autowired annotation: " +
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
if (candidate.getParameterTypes().length == 0) {
throw new IllegalStateException(
"Autowired annotation requires at least one argument: " + candidate);
}
boolean required = determineRequiredStatus(annotation);
boolean required = determineRequiredStatus(ann);
if (required) {
if (!candidates.isEmpty()) {
throw new BeanCreationException(
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructors: " + candidates +
". Found another constructor with 'required' Autowired annotation: " +
requiredConstructor);
". Found constructor with 'required' Autowired annotation: " +
candidate);
}
requiredConstructor = candidate;
}
@@ -265,8 +266,16 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
}
if (!candidates.isEmpty()) {
// Add default constructor to list of optional constructors, as fallback.
if (requiredConstructor == null && defaultConstructor != null) {
candidates.add(defaultConstructor);
if (requiredConstructor == null) {
if (defaultConstructor != null) {
candidates.add(defaultConstructor);
}
else if (candidates.size() == 1 && logger.isWarnEnabled()) {
logger.warn("Inconsistent constructor declaration on bean with name '" + beanName +
"': single autowire-marked constructor flagged as optional - this constructor " +
"is effectively required since there is no default constructor to fall back to: " +
candidates.get(0));
}
}
candidateConstructors = candidates.toArray(new Constructor<?>[candidates.size()]);
}
@@ -284,7 +293,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass());
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
}
@@ -302,7 +311,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
*/
public void processInjection(Object bean) throws BeansException {
Class<?> clazz = bean.getClass();
InjectionMetadata metadata = findAutowiringMetadata(clazz.getName(), clazz);
InjectionMetadata metadata = findAutowiringMetadata(clazz.getName(), clazz, null);
try {
metadata.inject(bean, null, null);
}
@@ -312,15 +321,18 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
}
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz) {
// Quick check on the concurrent map first, with minimal locking.
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (metadata == null) {
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (metadata == null) {
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
metadata = buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
@@ -336,23 +348,25 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
do {
LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<InjectionMetadata.InjectedElement>();
for (Field field : targetClass.getDeclaredFields()) {
AnnotationAttributes annotation = findAutowiredAnnotation(field);
if (annotation != null) {
AnnotationAttributes ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static fields: " + field);
}
continue;
}
boolean required = determineRequiredStatus(annotation);
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
}
for (Method method : targetClass.getDeclaredMethods()) {
AnnotationAttributes ann = null;
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
AnnotationAttributes annotation = BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod) ?
findAutowiredAnnotation(bridgedMethod) : findAutowiredAnnotation(method);
if (annotation != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
ann = findAutowiredAnnotation(bridgedMethod);
}
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static methods: " + method);
@@ -364,8 +378,8 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
logger.warn("Autowired annotation should be used on methods with actual parameters: " + method);
}
}
boolean required = determineRequiredStatus(annotation);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method, required, pd));
}
}
@@ -379,9 +393,9 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
AnnotationAttributes annotation = AnnotatedElementUtils.getAnnotationAttributes(ao, type.getName());
if (annotation != null) {
return annotation;
AnnotationAttributes ann = AnnotatedElementUtils.getAnnotationAttributes(ao, type.getName());
if (ann != null) {
return ann;
}
}
return null;
@@ -392,12 +406,12 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
* <p>A 'required' dependency means that autowiring should fail when no beans
* are found. Otherwise, the autowiring process will simply bypass the field
* or method when no beans are found.
* @param annotation the Autowired annotation
* @param ann the Autowired annotation
* @return whether the annotation indicates that a dependency is required
*/
protected boolean determineRequiredStatus(AnnotationAttributes annotation) {
return (!annotation.containsKey(this.requiredParameterName) ||
this.requiredParameterValue == annotation.getBoolean(this.requiredParameterName));
protected boolean determineRequiredStatus(AnnotationAttributes ann) {
return (!ann.containsKey(this.requiredParameterName) ||
this.requiredParameterValue == ann.getBoolean(this.requiredParameterName));
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,6 +34,7 @@ import org.springframework.util.ObjectUtils;
* Spring's {@link Qualifier @Qualifier} annotation.
*
* @author Chris Beams
* @author Juergen Hoeller
* @since 3.1.2
* @see BeanFactoryUtils
*/
@@ -90,9 +91,13 @@ public class BeanFactoryAnnotationUtils {
if (matchingBean != null) {
return matchingBean;
}
else if (bf.containsBean(qualifier)) {
// Fallback: target bean at least found by bean name - probably a manually registered singleton.
return bf.getBean(qualifier, beanType);
}
else {
throw new NoSuchBeanDefinitionException(qualifier, "No matching " + beanType.getSimpleName() +
" bean found for qualifier '" + qualifier + "' - neither qualifier " + "match nor bean name match!");
" bean found for qualifier '" + qualifier + "' - neither qualifier match nor bean name match!");
}
}
@@ -128,7 +133,7 @@ public class BeanFactoryAnnotationUtils {
}
}
catch (NoSuchBeanDefinitionException ex) {
// ignore - can't compare qualifiers for a manually registered singleton object
// Ignore - can't compare qualifiers for a manually registered singleton object
}
}
return false;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,7 +46,7 @@ import org.springframework.util.ReflectionUtils;
*/
public class InjectionMetadata {
private final Log logger = LogFactory.getLog(InjectionMetadata.class);
private static final Log logger = LogFactory.getLog(InjectionMetadata.class);
private final Class<?> targetClass;
@@ -60,6 +60,7 @@ public class InjectionMetadata {
this.injectedElements = elements;
}
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
Set<InjectedElement> checkedElements = new LinkedHashSet<InjectedElement>(this.injectedElements.size());
for (InjectedElement element : this.injectedElements) {
@@ -82,13 +83,31 @@ public class InjectionMetadata {
boolean debug = logger.isDebugEnabled();
for (InjectedElement element : elementsToIterate) {
if (debug) {
logger.debug("Processing injected method of bean '" + beanName + "': " + element);
logger.debug("Processing injected element of bean '" + beanName + "': " + element);
}
element.inject(target, beanName, pvs);
}
}
}
/**
* @since 3.2.13
*/
public void clear(PropertyValues pvs) {
Collection<InjectedElement> elementsToIterate =
(this.checkedElements != null ? this.checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
element.clearPropertySkipping(pvs);
}
}
}
public static boolean needsRefresh(InjectionMetadata metadata, Class<?> clazz) {
return (metadata == null || !metadata.targetClass.equals(clazz));
}
public static abstract class InjectedElement {
@@ -165,7 +184,7 @@ public class InjectionMetadata {
}
/**
* Checks whether this injector's property needs to be skipped due to
* Check whether this injector's property needs to be skipped due to
* an explicit property value having been specified. Also marks the
* affected property as processed for other processors to ignore it.
*/
@@ -196,6 +215,20 @@ public class InjectionMetadata {
}
}
/**
* @since 3.2.13
*/
protected void clearPropertySkipping(PropertyValues pvs) {
if (pvs == null) {
return;
}
synchronized (pvs) {
if (Boolean.FALSE.equals(this.skip) && this.pd != null && pvs instanceof MutablePropertyValues) {
((MutablePropertyValues) pvs).clearProcessedProperty(this.pd.getName());
}
}
}
/**
* Either this or {@link #inject} needs to be overridden.
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import java.util.Set;
import org.springframework.beans.SimpleTypeConverter;
import org.springframework.beans.TypeConverter;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.support.AutowireCandidateQualifier;
@@ -53,7 +54,7 @@ import org.springframework.util.StringUtils;
*/
public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwareAutowireCandidateResolver {
private final Set<Class<? extends Annotation>> qualifierTypes = new LinkedHashSet<Class<? extends Annotation>>();
private final Set<Class<? extends Annotation>> qualifierTypes = new LinkedHashSet<Class<? extends Annotation>>(2);
private Class<? extends Annotation> valueAnnotationType = Value.class;
@@ -66,9 +67,9 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
@SuppressWarnings("unchecked")
public QualifierAnnotationAutowireCandidateResolver() {
this.qualifierTypes.add(Qualifier.class);
ClassLoader cl = QualifierAnnotationAutowireCandidateResolver.class.getClassLoader();
try {
this.qualifierTypes.add((Class<? extends Annotation>) cl.loadClass("javax.inject.Qualifier"));
this.qualifierTypes.add((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Qualifier",
QualifierAnnotationAutowireCandidateResolver.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
@@ -216,22 +217,31 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
Class<? extends Annotation> type = annotation.annotationType();
RootBeanDefinition bd = (RootBeanDefinition) bdHolder.getBeanDefinition();
AutowireCandidateQualifier qualifier = bd.getQualifier(type.getName());
if (qualifier == null) {
qualifier = bd.getQualifier(ClassUtils.getShortName(type));
}
if (qualifier == null) {
Annotation targetAnnotation = null;
Method resolvedFactoryMethod = bd.getResolvedFactoryMethod();
if (resolvedFactoryMethod != null) {
targetAnnotation = AnnotationUtils.getAnnotation(resolvedFactoryMethod, type);
// First, check annotation on factory method, if applicable
Annotation targetAnnotation = getFactoryMethodAnnotation(bd, type);
if (targetAnnotation == null) {
RootBeanDefinition dbd = getResolvedDecoratedDefinition(bd);
if (dbd != null) {
targetAnnotation = getFactoryMethodAnnotation(dbd, type);
}
}
if (targetAnnotation == null) {
// look for matching annotation on the target class
// Look for matching annotation on the target class
if (getBeanFactory() != null) {
Class<?> beanType = getBeanFactory().getType(bdHolder.getBeanName());
if (beanType != null) {
targetAnnotation = AnnotationUtils.getAnnotation(ClassUtils.getUserClass(beanType), type);
try {
Class<?> beanType = getBeanFactory().getType(bdHolder.getBeanName());
if (beanType != null) {
targetAnnotation = AnnotationUtils.getAnnotation(ClassUtils.getUserClass(beanType), type);
}
}
catch (NoSuchBeanDefinitionException ex) {
// Not the usual case - simply forget about the type check...
}
}
if (targetAnnotation == null && bd.hasBeanClass()) {
@@ -242,30 +252,31 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
return true;
}
}
Map<String, Object> attributes = AnnotationUtils.getAnnotationAttributes(annotation);
if (attributes.isEmpty() && qualifier == null) {
// if no attributes, the qualifier must be present
// If no attributes, the qualifier must be present
return false;
}
for (Map.Entry<String, Object> entry : attributes.entrySet()) {
String attributeName = entry.getKey();
Object expectedValue = entry.getValue();
Object actualValue = null;
// check qualifier first
// Check qualifier first
if (qualifier != null) {
actualValue = qualifier.getAttribute(attributeName);
}
if (actualValue == null) {
// fall back on bean definition attribute
// Fall back on bean definition attribute
actualValue = bd.getAttribute(attributeName);
}
if (actualValue == null && attributeName.equals(AutowireCandidateQualifier.VALUE_KEY) &&
expectedValue instanceof String && bdHolder.matchesName((String) expectedValue)) {
// fall back on bean name (or alias) match
// Fall back on bean name (or alias) match
continue;
}
if (actualValue == null && qualifier != null) {
// fall back on default, but only if the qualifier is present
// Fall back on default, but only if the qualifier is present
actualValue = AnnotationUtils.getDefaultValue(annotation, attributeName);
}
if (actualValue != null) {
@@ -278,6 +289,11 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
return true;
}
protected Annotation getFactoryMethodAnnotation(RootBeanDefinition bd, Class<? extends Annotation> type) {
Method resolvedFactoryMethod = bd.getResolvedFactoryMethod();
return (resolvedFactoryMethod != null ? AnnotationUtils.getAnnotation(resolvedFactoryMethod, type) : null);
}
/**
* Determine whether the given dependency carries a value annotation.
@@ -30,6 +30,7 @@ import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
@@ -165,6 +166,8 @@ public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanP
* required property check as performed by this post-processor.
* <p>The default implementations check for the presence of the
* {@link #SKIP_REQUIRED_CHECK_ATTRIBUTE} attribute in the bean definition, if any.
* It also suggests skipping in case of a bean definition with a "factory-bean"
* reference set, assuming that instance-based factories pre-populate the bean.
* @param beanFactory the BeanFactory to check against
* @param beanName the name of the bean to check against
* @return {@code true} to skip the bean; {@code false} to process it
@@ -173,7 +176,11 @@ public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanP
if (beanFactory == null || !beanFactory.containsBeanDefinition(beanName)) {
return false;
}
Object value = beanFactory.getBeanDefinition(beanName).getAttribute(SKIP_REQUIRED_CHECK_ATTRIBUTE);
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
if (beanDefinition.getFactoryBeanName() != null) {
return true;
}
Object value = beanDefinition.getAttribute(SKIP_REQUIRED_CHECK_ATTRIBUTE);
return (value != null && (Boolean.TRUE.equals(value) || Boolean.valueOf(value.toString())));
}
@@ -0,0 +1,132 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.config;
import java.lang.reflect.InvocationTargetException;
import org.springframework.beans.TypeConverter;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.support.ArgumentConvertingMethodInvoker;
import org.springframework.util.ClassUtils;
/**
* Simple method invoker bean: just invoking a target method, not expecting a result
* to expose to the container (in contrast to {@link MethodInvokingFactoryBean}).
*
* <p>This invoker supports any kind of target method. A static method may be specified
* by setting the {@link #setTargetMethod targetMethod} property to a String representing
* the static method name, with {@link #setTargetClass targetClass} specifying the Class
* that the static method is defined on. Alternatively, a target instance method may be
* specified, by setting the {@link #setTargetObject targetObject} property as the target
* object, and the {@link #setTargetMethod targetMethod} property as the name of the
* method to call on that target object. Arguments for the method invocation may be
* specified by setting the {@link #setArguments arguments} property.
*
* <p>This class depends on {@link #afterPropertiesSet()} being called once
* all properties have been set, as per the InitializingBean contract.
*
* <p>An example (in an XML based bean factory definition) of a bean definition
* which uses this class to call a static initialization method:
*
* <pre class="code">
* &lt;bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingBean">
* &lt;property name="staticMethod" value="com.whatever.MyClass.init"/>
* &lt;/bean></pre>
*
* <p>An example of calling an instance method to start some server bean:
*
* <pre class="code">
* &lt;bean id="myStarter" class="org.springframework.beans.factory.config.MethodInvokingBean">
* &lt;property name="targetObject" ref="myServer"/>
* &lt;property name="targetMethod" value="start"/>
* &lt;/bean></pre>
*
* @author Juergen Hoeller
* @since 4.0.3
* @see MethodInvokingFactoryBean
* @see org.springframework.util.MethodInvoker
*/
public class MethodInvokingBean extends ArgumentConvertingMethodInvoker
implements BeanClassLoaderAware, BeanFactoryAware, InitializingBean {
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
private ConfigurableBeanFactory beanFactory;
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
@Override
protected Class<?> resolveClassName(String className) throws ClassNotFoundException {
return ClassUtils.forName(className, this.beanClassLoader);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
if (beanFactory instanceof ConfigurableBeanFactory) {
this.beanFactory = (ConfigurableBeanFactory) beanFactory;
}
}
/**
* Obtain the TypeConverter from the BeanFactory that this bean runs in,
* if possible.
* @see ConfigurableBeanFactory#getTypeConverter()
*/
@Override
protected TypeConverter getDefaultTypeConverter() {
if (this.beanFactory != null) {
return this.beanFactory.getTypeConverter();
}
else {
return super.getDefaultTypeConverter();
}
}
@Override
public void afterPropertiesSet() throws Exception {
prepare();
invokeWithTargetException();
}
/**
* Perform the invocation and convert InvocationTargetException
* into the underlying target exception.
*/
protected Object invokeWithTargetException() throws Exception {
try {
return invoke();
}
catch (InvocationTargetException ex) {
if (ex.getTargetException() instanceof Exception) {
throw (Exception) ex.getTargetException();
}
if (ex.getTargetException() instanceof Error) {
throw (Error) ex.getTargetException();
}
throw ex;
}
}
}

Some files were not shown because too many files have changed in this diff Show More