Compare commits

..

341 Commits

Author SHA1 Message Date
Spring Buildmaster 5b99ee2990 Release version 3.2.7 2014-01-28 14:38:30 -08:00
Phillip Webb 3ba7ab15ab Update changelog 2014-01-28 13:53:01 -08:00
Juergen Hoeller 36ab65ace7 Dropped explicit paragraph on web.xml version declaration
Issue: SPR-11364
2014-01-28 17:32:08 +01:00
Juergen Hoeller 35753eb54d Backported test for fallback for non-resolvable property type
(cherry picked from commit 8570f60)
2014-01-28 17:25:12 +01:00
Brian Clozel 1cb9b9cf52 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
(cherry picked from commit 425e5a0)
2014-01-28 12:41:36 +01:00
Juergen Hoeller fe4b57c199 Fixed 'globalJobListeners'/'globalTriggerListeners' to work with Quartz 2.0 & 2.1 as well
Issue: SPR-11362
(cherry picked from commit c719c70)
2014-01-28 12:41:29 +01:00
Juergen Hoeller 2a3b29f98e Upgraded to SLF4J 1.6.6 2014-01-28 01:46:41 +01:00
Juergen Hoeller d26a570192 Polishing 2014-01-28 01:46:19 +01:00
Juergen Hoeller ac3c670f70 Fixed type resolution in case of inconsistencies between read and write method
Issue: SPR-11361
2014-01-28 01:20:27 +01:00
Juergen Hoeller 398f91cb74 Polishing 2014-01-27 22:49:14 +01:00
Juergen Hoeller b4115f3202 Downgraded JOpt build dependency to 3.3
Avoiding accidental use of OptionSet.specs(), as introduced in the JOpt 4.x line.
2014-01-27 22:15:54 +01:00
Juergen Hoeller 7e2167fd17 Specific deprecations and consistent setter varargs in Hibernate support
Issue: SPR-11291
2014-01-27 22:11:58 +01:00
Juergen Hoeller 09ad8347be Downgraded Commons Pool dependency to 1.5.7
Commons Pool 1.6 introduced generics in its APIs, leading to either a 1.6 dependency at runtime or a load of raw type warnings in our CommonsPoolTargetSource.
2014-01-26 00:41:59 +01:00
Juergen Hoeller 2ef39a5666 Consistently declare @SuppressWarnings("serial") instead of dummy serialVersionUID
(cherry picked from commit 56b7d7a)
2014-01-26 00:37:09 +01:00
Juergen Hoeller 1a2033eb41 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
(cherry picked from commit 67e76e9)
2014-01-26 00:37:03 +01:00
Juergen Hoeller 6162917b4e Consistently switched optional dependencies to scope 'optional'; consistently grouped dependency scopes; minor dependency version updates 2014-01-25 22:12:16 +01:00
Juergen Hoeller e07ad5a19b Polishing 2014-01-25 00:15:00 +01:00
Juergen Hoeller 5307a87d1a Polishing
Issue: SPR-11357
2014-01-24 19:19:32 +01:00
Juergen Hoeller 87179b075b Optimized Introspector.flushFromCaches calls to skip Object.class
Issue: SPR-11356
2014-01-24 19:18:39 +01:00
Juergen Hoeller 23249cda98 Added test for SpringProperties setFlag method
Issue: SPR-9014
Issue: SPR-11297
2014-01-24 17:48:40 +01:00
Juergen Hoeller 341d645d09 Polishing
Issue: SPR-11357
2014-01-24 17:46:56 +01:00
Juergen Hoeller 9845d9eb21 Allow consolidating config in root context with Java
Issue: SPR-11357
(backported from 4.0.1)
2014-01-24 17:46:31 +01:00
Juergen Hoeller edb660863b Polishing 2014-01-24 16:59:42 +01:00
Juergen Hoeller 866c7847e3 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
(cherry picked from commit 8543b91)
2014-01-24 16:58:16 +01:00
Juergen Hoeller fc361844ec Polishing
Issue: SPR-11297
2014-01-22 23:57:48 +01:00
Juergen Hoeller 52d050d21a Factored out "suppressGetenvAccess()" method
Issue: SPR-11297
2014-01-22 23:57:36 +01:00
Sam Brannen c1569d7ecd 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

Backport-Commit: fb12e234fc
2014-01-22 23:40:56 +01:00
Juergen Hoeller fdd31c0e66 Preserve visitBeanDefinition stacktrace in BeanDefinitionStoreException
Issue: SPR-11346
2014-01-22 22:40:10 +01:00
Juergen Hoeller cfa78a9b25 Quick paragraph on mvc namespace and matrix variables
Issue: SPR-11331
2014-01-22 22:37:22 +01:00
Juergen Hoeller d434ef9713 Polishing
Issue: SPR-11344
2014-01-22 18:23:59 +01:00
Juergen Hoeller c406c56d57 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
2014-01-22 18:23:09 +01:00
Juergen Hoeller d9ab6aaf6c 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
(cherry picked from commit a599b57)
2014-01-22 14:48:26 +01:00
Juergen Hoeller aa1babdfde Fixed setDeliveryPersistent javadoc
Issue: SPR-3983
(cherry picked from commit 9cc86a3)
2014-01-21 17:13:33 +01:00
Juergen Hoeller 09c9137b75 Removed accidental backport of StAX code in 3.2.5 (restoring Java 5 compatibility)
Issue: SPR-11341
2014-01-21 17:12:22 +01:00
Sam Brannen 603d79ac9b 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

Backport-Commit: 3370f8b1b1
2014-01-21 15:18:59 +01:00
Sam Brannen fdac4a7d18 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

Backport-Commit: 098d7c7465
2014-01-21 15:16:55 +01:00
Juergen Hoeller 11ef4308b8 Polishing 2014-01-21 01:55:09 +01:00
Juergen Hoeller e0f9a85955 Locale/ThemeChangeInterceptor alignment and javadoc polishing
Issue: SPR-11128
(cherry picked from commit 5e5add4)
2014-01-21 01:39:02 +01:00
Juergen Hoeller b229d54172 Consistent evaluation of empty theme names to default theme name
Issue: SPR-11128
(cherry picked from commit cc81aae)
2014-01-21 01:38:03 +01:00
Juergen Hoeller c77832ba6d Added info-level logging for default unit detection
Issue: SPR-11333
(cherry picked from commit 88730bd)
2014-01-21 01:36:50 +01:00
Juergen Hoeller 59893d1f13 Fixed assert in setAspectJAdvisorFactory()
Issue: SPR-11330
(cherry picked from commit f15a5fe)
2014-01-21 01:34:47 +01:00
Juergen Hoeller 9aefa0334f Polishing 2014-01-16 18:28:50 +01:00
Juergen Hoeller f532607d4b Introduced customizeConnection callbacks for URLConnection used by exists() / contentLength() / lastModified()
Issue: SPR-11320
(cherry picked from commit 4f45ad5)
2014-01-16 17:54:44 +01:00
Juergen Hoeller 16bf501b30 Polishing 2014-01-16 17:53:26 +01:00
Juergen Hoeller fd13c994c9 Fixed accidental use of String.isEmpty in SimpleCommandLineArgsParser
Issue: SPR-11321
2014-01-16 17:35:49 +01:00
Juergen Hoeller 1f60738431 checkNotModified needs to consider HEAD as well
Issue: SPR-11317
(cherry picked from commit 17cc63e)
2014-01-15 23:47:16 +01:00
Juergen Hoeller 68b1eb1aba Polishing 2014-01-15 23:46:52 +01:00
Juergen Hoeller 5fb2665d1c Introduced "globalInitializerClasses" next to the existing "contextInitializerClasses", applying to FrameworkServlets as well
Issue: SPR-11314
(cherry picked from commit 91881ff)
2014-01-15 23:46:04 +01:00
Juergen Hoeller 52c11eab41 Polishing
(cherry picked from commit e670f4e)
2014-01-15 17:54:37 +01:00
Juergen Hoeller b6362c5016 Introduced "spring.getenv.ignore" system property for preventing System.getenv calls
Issue: SPR-11297
(cherry picked from commit 961f42b)
2014-01-15 17:52:36 +01:00
Juergen Hoeller 6deb597cdf Removed Commons Lang references and refined Java 5+ implementation details 2014-01-15 15:56:03 +01:00
Juergen Hoeller bfecbaf88e Clarified ArgsMatchKind deprecation 2014-01-15 15:46:46 +01:00
Juergen Hoeller 3429a4186c Polishing 2014-01-15 15:16:01 +01:00
Juergen Hoeller f18debb5a3 Fixed getTypeDifferenceWeight algorithm in ReflectionHelper, and deprecated ArgsMatchKind enum (for removal in 4.0)
Issue: SPR-11306
2014-01-15 15:15:39 +01:00
Juergen Hoeller 62fd12c527 Restored Java 5 compatibility through avoiding Collections.newSetFromMap
Issue: SPR-11313
2014-01-15 14:14:50 +01:00
Juergen Hoeller f8f6c5fd89 Polishing 2014-01-13 23:49:39 +01:00
Juergen Hoeller 354917c53d Polishing (backports from 4.0.1) 2014-01-13 23:36:33 +01:00
Juergen Hoeller 1e0bf493cc Backported generics/varargs signature refinements for scripting package 2014-01-13 23:30:21 +01:00
Juergen Hoeller 0ea4f8ecb7 Fixed resolveProxyTargetClass exception message 2014-01-13 23:21:33 +01:00
Juergen Hoeller 139adba96a Removed TestGroup.LONG_RUNNING marker from Groovy and JRuby tests 2014-01-13 23:21:16 +01:00
Juergen Hoeller 7502ecd35e CronTriggerFactoryBean allows 'calendarName' and 'description' to be specified
Also making 'description' available on SimpleTriggerFactoryBean.

Issue: SPR-9771
2014-01-13 23:18:31 +01:00
Juergen Hoeller 477e60f28a Add minor optimization to AbstractErrors
Issue: SPR-11304
2014-01-13 23:15:50 +01:00
Juergen Hoeller 3db6a7f715 Add method for HTTP PATCH in MockMvcRequestBuilders
Issue: SPR-11299
2014-01-13 23:14:52 +01:00
Juergen Hoeller 0606c98277 Polishing (along with the Tiles 2.2.2 upgrade in the Spring 4.0 line)
Issue: SPR-11285
2014-01-06 00:43:41 +01:00
Juergen Hoeller dbfe68a6dc Further polishing
Issue: SPR-10940
2014-01-05 22:08:02 +01:00
Juergen Hoeller ab6c6b104d Consistent support for setStartTime in CronTrigger(Factory)Bean and SimpleTrigger(Factory)Bean, and consistent declaration of varargs in scheduling.quartz package
Issue: SPR-10940
(cherry picked from commit b228a06)
2014-01-05 18:03:54 +01:00
Juergen Hoeller c2459b4a61 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
(cherry picked from commit 38a8ace)
2014-01-05 18:03:27 +01:00
Juergen Hoeller 4f24643fd3 Upgraded selected build dependencies to early 2013 releases 2014-01-05 02:47:44 +01:00
Juergen Hoeller 1a0a381559 Made findMethodAnnotationOnBridgeMethod compatible with Java 8 2014-01-05 02:30:04 +01:00
Juergen Hoeller 8c8eead667 Removed AbstractAsyncConfiguration's abstract "asyncAdvisor" method for Java 8 compatibility (to avoid method overloading problem for configuration classes) 2014-01-05 02:28:27 +01:00
Juergen Hoeller b35050caf2 Fixed Jackson2ObjectMapperFactoryBean class name in javadoc examples 2014-01-05 02:24:13 +01:00
Juergen Hoeller 72a5737ab9 Polishing 2014-01-05 00:02:54 +01:00
Juergen Hoeller be2d915cc2 Consistent equals/hashCode/toString implementations in AnnotationMatchingPointcut/ClassFilter/MethodMatcher
Issue: SPR-11275
Issue: SPR-11276
(cherry picked from commit 0de307b)
2014-01-05 00:02:47 +01:00
Juergen Hoeller 6045914057 Polishing 2014-01-03 23:02:51 +01:00
Juergen Hoeller 78646f1f32 Activated through rename to *Tests, and added method call interaction tests
Issue: SPR-7831
(cherry picked from commit 3bed6cf)
2014-01-03 23:02:18 +01:00
Juergen Hoeller f88cbda6ef Introduced "spring.beaninfo.ignore" system property for optimized Introspector usage
Issue: SPR-9014
2014-01-03 14:14:10 +01:00
Juergen Hoeller c48da0d9a4 Avoid hard reference to LocalValidatorFactoryBean in <mvc:annotation-driven> parser
Issue: SPR-11272
2014-01-03 12:18:49 +01:00
Juergen Hoeller e3344898cd Support varargs for DomUtils.getChildElementsByTagName
Issue: SPR-11272
2014-01-03 12:18:19 +01:00
Juergen Hoeller 2e123b01e5 Polishing
Issue: SPR-11259
(cherry picked from commit f0d2151)
2014-01-01 19:24:37 +01:00
Juergen Hoeller 57eedf33d6 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
(cherry picked from commit 82ea9ec)
2014-01-01 19:18:39 +01:00
Juergen Hoeller f477a024ad EhCacheFactoryBean does not call set(Sampled)StatisticsEnabled on EhCache 2.7/2.8
Issue: SPR-11265
(cherry picked from commit 73d8f06)
2014-01-01 19:18:12 +01:00
Juergen Hoeller 5dddb492b8 Polishing around @Enable processing and @EnableTransactionManagement
Issue: SPR-11251
2013-12-23 23:09:00 +01:00
Juergen Hoeller ecee20f1fe @Enable registrars called with correct metadata when placed on superclass
Issue: SPR-11251
2013-12-23 23:07:59 +01:00
Juergen Hoeller e08f743301 ResourceDatabasePopulator's setScripts takes varargs
(cherry picked from commit e3017c3)
2013-12-23 23:05:34 +01:00
Juergen Hoeller a05c957d0e Polishing
Issue: SPR-11254
(cherry picked from commit 9a39f39)
2013-12-23 23:05:10 +01:00
Juergen Hoeller a2de329db9 Revised XMLEventStreamWriter to allow for empty elements with attributes
Issue: SPR-11254
(cherry picked from commit ee5b7fd)
2013-12-23 23:04:58 +01:00
Juergen Hoeller 551364f668 Polishing 2013-12-20 00:40:14 +01:00
Juergen Hoeller 08aa22ff1f InjectionMetadata caching per bean name needs to refresh when bean class changes
Issue: SPR-11246
2013-12-20 00:15:09 +01:00
Juergen Hoeller a115a7dad5 Revised BeanInfoFactory javadoc
Issue: SPR-9014
2013-12-20 00:09:49 +01:00
Juergen Hoeller f457319965 Consistent non-declaration of serialVersionUID 2013-12-20 00:06:40 +01:00
Juergen Hoeller 7ad6df8c75 Moved AnnotationBeanNameGenerator's String value check right before cast
Issue: SPR-11221
2013-12-20 00:02:27 +01:00
Juergen Hoeller f5d5882f46 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
(cherry picked from commit 105e176)
2013-12-16 23:09:07 +01:00
Juergen Hoeller 0a4d28d5d5 Fixed primitive type assignability in BeanUtils.copyProperties
Issue: SPR-11231
(cherry picked from commit 8a3b4c6)
2013-12-16 22:57:50 +01:00
Spring Buildmaster 9002742873 Next development version 2013-12-12 01:07:15 -08:00
Phillip Webb c2d98de6a6 Update changelog 2013-12-12 00:28:01 -08:00
Juergen Hoeller bf31f7178d Polishing
(cherry picked from commit a3a4344)
2013-12-11 23:58:16 +01:00
Juergen Hoeller 249d8379ae Polishing
(cherry picked from commit aa6e6c1)
2013-12-11 23:12:34 +01:00
Juergen Hoeller bfcfbe41a1 Made BeanUtils.copyProperties defensive about property type mismatches
Issue: SPR-11209
(cherry picked from commit bc5affa)
2013-12-11 23:12:33 +01:00
Phillip Webb f17ae5a7a8 Replace references to VMware with Pivotal
Replace references to VMware in license, notices and maven generation
with Pivotal, Inc.

Issue: SPR-11073
(cherry picked from commit b085ec9)
2013-12-11 14:10:28 -08:00
Juergen Hoeller 779d5716e5 Moved RequiredAnnotationBeanPostProcessorTests to correct package beans.factory.annotation 2013-12-11 18:45:23 +01:00
Juergen Hoeller 2a6c642408 Added tests for custom qualifier annotations on scoped @Bean methods
Issue: SPR-11116
(cherry picked from commit c5d7977)
2013-12-11 18:44:13 +01:00
Juergen Hoeller 126116e759 DispatcherPortlet never uses a resource forward on Liferay
Issue: SPR-10791
(cherry picked from commit 9c157ea)
2013-12-11 18:43:58 +01:00
Juergen Hoeller 1ea218cee2 MBean registration happens in a fully synchronized fashion for consistent results
Issue: SPR-11002
(cherry picked from commit 8d6d6be)
2013-12-11 18:43:33 +01:00
Juergen Hoeller ec78165072 Component scanning ignores attributes and meta-annotations on non-public annotations
Issue: SPR-11091
(cherry picked from commit 161819f)
2013-12-11 18:42:48 +01:00
Juergen Hoeller e4fb72f6e3 Fixed CGLIB class validation to not raising warning for static final methods
Issue: SPR-11107
(cherry picked from commit 9fbb57c)
2013-12-11 17:46:23 +01:00
Juergen Hoeller 6fb10981b0 Fixed extractOutputParameters to properly extract ResultSet in all cases
Issue: SPR-11076
(cherry picked from commit 3ff3805)
2013-12-11 17:45:51 +01:00
Juergen Hoeller d48b9b1ef7 Actually accept String expressions for "prefetch" and "receive-timeout" in jms namespace
Issue: SPR-10986
(cherry picked from commit ccafccb)
2013-12-11 17:45:15 +01:00
Juergen Hoeller c3907cdae5 Added 546 to Sybase data integrity violation codes
Issue: SPR-11097
(cherry picked from commit 2d2226b)
2013-12-11 17:44:47 +01:00
Juergen Hoeller 7f895222e1 Revised exclusion of java.lang.Class properties
Issue: SPR-11098
(cherry picked from commit 62ea627)
2013-12-11 17:44:16 +01:00
Phillip Webb 22ece06b39 Add a 'bill of materials' project for Maven users
Add 'spring-framework-bom' meta-project that contains the other projects
in a dependencyManagement section.

Issue: SPR-11138
2013-12-11 10:01:23 -06:00
Sam Brannen b20b7415d8 Make methods of TestContext non-final
This commit makes several methods of TestContext non-final in order to
allow TestContext to be mocked — for example with Mockito.

Note, however, that TestContext has been converted to an interface in
Spring Framework 4.0.

Issue: SPR-11144
2013-12-11 01:23:03 +01:00
Sam Brannen 38ad39f467 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

Backport-Commit: 800018a817
2013-12-11 01:02:05 +01:00
Sam Brannen 6ded287144 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

Backport-Commit: 099b10d23b
2013-12-10 23:54:05 +01:00
Juergen Hoeller 6e275b7663 Polishing 2013-12-10 22:48:42 +01:00
Juergen Hoeller 882726377f 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
(cherry picked from commit cb624e2)
2013-12-10 22:48:35 +01:00
Juergen Hoeller 2e15f94cf2 Optimized use of JDBC 3.0 ParameterMetaData.getParameterType, caching information about drivers which do not support that feature
Issue: SPR-11100
(cherry picked from commit 4c8a789)
2013-12-10 13:14:13 +01:00
Juergen Hoeller d0fc38ec76 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
(cherry picked from commit 242ecdc)
2013-12-10 13:12:41 +01:00
Juergen Hoeller 8e52e650f4 Fixed type resolution for uninitialized factory-method declaration
Issue: SPR-11112
(cherry picked from commit 5dcd287)
2013-12-10 13:12:32 +01:00
Juergen Hoeller 71650c0a44 Fixed evaluation of "!" operator in case of multiple profile expressions
Issue: SPR-11093
(cherry picked from commit 6078c27)
2013-12-10 12:16:22 +01:00
Sam Brannen c89985c1db 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

Backport-Commit: a3b022aa48
2013-12-09 15:43:32 +01:00
Juergen Hoeller d4b0751626 Polishing 2013-12-09 00:12:03 +01:00
Juergen Hoeller 6bed18004e Fixed detection of qualifier annotations on scoped-proxy factory methods
Issue: SPR-11116
2013-12-09 00:11:41 +01:00
Phillip Webb dfed8afb26 Only consider "is" methods with boolean returns
Fix regression introduced in b25e91a5 where ReflectivePropertyAccessor
does not consider the return type for "is" getters.

Issue: SPR-11142
(cherry picked from commit 85b0bfff)
2013-12-03 12:06:26 -08:00
Rossen Stoyanchev 236981aaa9 Support multi-value x-forwarded-host header
Issue: SPR-11140
2013-12-03 09:55:47 -05:00
Juergen Hoeller 6ce2eb9622 EhCacheFactoryBean calls CacheManager.addCache before setStatisticsEnabled
Issue: SPR-11080
Issue: SPR-11092
2013-12-03 01:30:22 +01:00
Juergen Hoeller 6224ddd0cb Polishing (including removal of javadoc imports that show as package cycles in IntelliJ)
(cherry picked from commit 2a52dec)
2013-12-03 01:28:45 +01:00
Juergen Hoeller 25c7e3645b Polishing (including removal of javadoc imports that show as package cycles in IntelliJ)
(cherry picked from commit 2a52dec)
2013-12-03 00:00:31 +01:00
Juergen Hoeller 9c9cc7fcb4 Use AnnotationTransactionAttributeSource class name to avoid hard dependency on transaction.annotation package
(cherry picked from commit 4133272)
2013-12-02 23:59:36 +01:00
Juergen Hoeller 5639eb66b6 Polishing 2013-12-02 16:32:02 +01:00
Juergen Hoeller 1dc79f7f9c Synchronized cache creation on CacheManager
Issue: SPR-11132
(cherry picked from commit de890fd)
2013-12-02 16:10:44 +01:00
Juergen Hoeller c1b772cd9c Optimized ImportAware processing to avoid re-reading class files
(cherry picked from commit 519f78c)
2013-12-02 16:10:34 +01:00
Phillip Webb 73a8a1b966 Detect cache hit with multiple @Cachables
Fix CacheAspectSupport to consider a cache hit from any of the multiple
@Cachables that may have been specified using the @Caching annotation.

Prior to this commit the following scenario would never produce a hit:

    @Caching(cacheable = {
            @Cacheable(value = "c1", unless = "#result.size() < 4"),
            @Cacheable(value = "c2", unless = "#result.size() > 3")
     })

Issue: SPR-11124
2013-11-26 17:13:50 -08:00
Spring Buildmaster 0f26a7795d Next development version 2013-11-06 11:51:48 -08:00
Phillip Webb 47ae15b7ee Update changelog 2013-11-06 11:15:37 -08:00
Juergen Hoeller df7b661702 Added test for placeholder in alias definition
Issue: SPR-11018
(cherry picked from commit e9a24da)
2013-11-06 00:36:56 +01:00
Juergen Hoeller fe46a01a57 JndiObjectFactoryBean converts a "defaultObject" value to the expected type if necessary
Issue: SPR-11039
(cherry picked from commit 0aedd81)
2013-11-06 00:36:48 +01:00
Rossen Stoyanchev 2f13e05b4f Return 415 on bad request body content-type
Issue: SPR-10982
2013-11-05 15:38:04 -05:00
Rossen Stoyanchev 4b38dc8972 Fix exception mock request builder
Issue: SPR-11043
2013-11-05 11:00:02 -05:00
Rossen Stoyanchev 7387cb990e Disable ext entities in SourceHttpMessageConverter
This change disables the processing of external entities in
SourceHttpMessageConverter by default and provides an option to enable
it if required.
2013-11-05 09:49:13 -05:00
Juergen Hoeller 863570abb7 Perform setParent's Environment merging for ClassPathXmlApplicationContext etc constructors with parent argument as well
Issue: SPR-11068
(cherry picked from commit c5fcf19)
2013-11-05 14:18:14 +01:00
Juergen Hoeller 70907fd326 Only retrieve the FlashMapManager if a non-empty output FlashMap has been found
Issue: SPR-10937
(cherry picked from commit 4ac6801)
2013-11-05 14:18:08 +01:00
Juergen Hoeller 494cc22bcd Polishing (along with SPR-10992) 2013-11-05 00:52:49 +01:00
Juergen Hoeller 044d68b336 @Bean method metadata is always being picked from the most concrete subclass
As a side effect, @Bean overrides and overloads work with 'allowBeanDefinitionOverriding'=false as well now.

Issue: SPR-10992
2013-11-05 00:52:28 +01:00
Juergen Hoeller a95eb1d044 Polishing (selectively backported from recent 4.0 commits) 2013-11-04 16:22:46 +01:00
Juergen Hoeller b00c31a620 Use non-lenient constructor resolution mode for @Bean methods
Since @Bean methods are never used with externally specified constructor argument values but rather just with autowiring, the non-lenient constructor resolution mode is appropriate in case of an overloaded @Bean method, not performing any type difference weight checks. This change includes a refinement of Spring's existing non-lenient constructor resolution (which needs to be explicitly turned on and is therefore not well tested), narrowing the conditions for the ambiguity check (only in case of the same number of arguments and not for overridden methods).

Issue: SPR-10988
(cherry picked from commit b093b84)
2013-11-04 16:11:04 +01:00
Juergen Hoeller 23cc44f16e Javadoc polishing 2013-11-01 23:04:07 +01:00
Juergen Hoeller e1a065906e Avoid unnecessary char[] allocation in NamedParameterUtils
Issue: SPR-11042
(cherry picked from commit 1dc7ff8)
2013-11-01 23:02:56 +01:00
Juergen Hoeller 3bfddc501d Backported further GenericTypeResolver tests
Issue: SPR-11052
2013-10-31 17:39:39 +01:00
Rossen Stoyanchev f9081bedb4 Add timeout async request handling to OSIV components
This change adds async web request timeout handling to OSIV filters
and interceptors to ensure the session or entity manager is released.

Issue: SPR-10874
2013-10-30 23:12:09 -04:00
Juergen Hoeller 1ac8e48ebf Polishing (backported from several master changes) 2013-10-30 22:47:16 +01:00
Rossen Stoyanchev d4f4225e53 Avoid filling up AntPathMatcher cache
This change avoid use of AntPathMatcher to extract URI template
variables when the lookup path is used as the best matching pattern.

Issue: SPR-10803
(cherry picked from commit a7af950)
2013-10-30 22:18:11 +01:00
Juergen Hoeller c53184cb6d Refined logging for advisors which are currently in creation
Issue: SPR-10430
(cherry picked from commit 62157fe)
2013-10-30 22:12:24 +01:00
Phillip Webb f9f106936c Relax JavaBean rules for SpEL property access
Relax the method search algorithm used by `ReflectivePropertyAccessor`
to include methods of the form `getXY()` for properties of the form
`xy`.

Although the JavaBean specification indicates that a property `xy`
should use the accessors `getxY()` and `setxY()`, in practice many
developers choose to have an uppercase first character. The
`ReflectivePropertyAccessor` will now consider these style methods if
the traditional conventions fail to find a match.

Issue: SPR-10716
(cherry picked from commit b25e91a5)
2013-10-30 13:02:07 -07:00
Phillip Webb bcf7aecf0f Skip convert to Object from TypeConverterDelegate
Update TypeConverterDelegate to bypass conversion when the target type
is Object.class. Prior to this commit converting a single element array
to an Object would result in the element being returned, rather than
the array itself.

Issue: SPR-10996
(cherry picked from commit c9aace4d)
2013-10-30 13:02:07 -07:00
Phillip Webb 5854d519a1 Add targetIsClass to SpEL property cache key
Update the `CacheKey` class used by `ReflectivePropertyAccessor` to
include if the target object is class. The prevents an incorrect cache
hit from being returned when a property with the same name is read on
both an object and its class. For example:

	#{class.name}
	#{name}

Issue: SPR-10486
(cherry picked from commit 6d882b14)
2013-10-30 13:02:07 -07:00
Phillip Webb 1ea7f741fe Multicaster support for events with null source
Update `AbstractApplicationEventMulticaster` to support `EventObjects`
with a null source (which can happen if they have been serialized).

Issue: SPR-10945
(cherry picked from commit b0ff834e)
2013-10-30 13:02:07 -07:00
Phillip Webb 8c6fe2cb42 Consistent ordering for @PropertySource locations
Ensure that property source locations are processed in the same order
regardless if the 'name' attribute is set or not.

Prior to this commit multiple locations from a `@PropertySource` with
a name were added to a `CompositePropertySource` in such a way that
the first location would take precedence. This has now been reversed
for consistence with unnamed `@PropertySource`s

Issue: SPR-10820
(cherry picked from commit e3d3d8cd)
2013-10-30 13:02:06 -07:00
Rossen Stoyanchev 7a5a6893e3 Avoid filling up AntPathMatcher cache
This change avoid use of AntPathMatcher to extract URI template
variables when the lookup path is used as the best matching pattern.

Issue: SPR-10803
2013-10-30 14:34:13 -04:00
Juergen Hoeller c8e8d6cd49 Defensive handling of exceptions during factory method type checking
Also using ClassUtils.forName in AutowireUtils now in order to accept all common class name formats.

Issue: SPR-11034
(cherry picked from commit 8c1767e)
2013-10-28 13:47:11 +01:00
Juergen Hoeller 094ff8883d Polishing 2013-10-27 22:52:36 +01:00
Juergen Hoeller 44f79f95a7 Fixed resolveReturnTypeForFactoryMethod to unwrap TypedStringValue
XML-defined arguments values are initially turned into TypedStringValue wrappers. If we encounter an unresolved argument, we need to unwrap such a TypedStringValue and then try to treat its content as a class name.

Issue: SPR-11034
2013-10-27 22:48:57 +01:00
Juergen Hoeller 3eaec64ee8 Fixed source location of setEncoding method 2013-10-27 00:57:37 +02:00
Juergen Hoeller ff9c695599 Minor optimizations in factory method handling
Optimized getTypeForFactoryMethod's implementation for non-generic factory methods, and reduced calls to getResolvedFactoryMethod in order to avoid repeated synchronization. Derived from work around SPR-11034.
2013-10-27 00:55:02 +02:00
Juergen Hoeller 6021822ce4 Polishing 2013-10-26 17:31:43 +02:00
Juergen Hoeller 045f78e6c5 Fixed detection of setter in case of getter with covariant return type narrowing
Issue: SPR-10995
2013-10-26 17:31:24 +02:00
Juergen Hoeller 42568afb37 Factory method type resolution works with indexed and named arguments as well
Issue: SPR-11019
(cherry picked from commit 109faac)
2013-10-26 15:57:54 +02:00
Juergen Hoeller ce001c23f7 Cache InjectionMetadata per bean name instead of per Class, if possible
Issue: SPR-11027
(cherry picked from commit 4675bc4)
2013-10-26 15:56:57 +02:00
Juergen Hoeller 93405fb289 Made processCommonDefinitionAnnotations(AnnotatedBeanDefinition) public
Issue: SPR-11032
(cherry picked from commit 8bd4804)
2013-10-26 15:55:48 +02:00
Juergen Hoeller db056ae0e0 ExpressionState.getConfiguration() should never return null
Issue: SPR-11031
(cherry picked from commit 4aab315)
2013-10-26 15:55:13 +02:00
Juergen Hoeller 35d53af2ca Removed accidentally added temporary files 2013-10-26 15:54:46 +02:00
Sam Brannen 63de2fab4c Assert context uniqueness against merged config
Prior to this commit, the uniqueness check for @ContextConfiguration
attributes within a @ContextHierarchy was performed at a single test
class level instead of against the merged configuration for all test
class levels in the test class hierarchy.

This commit addresses this issue by moving the uniqueness check
algorithm from resolveContextHierarchyAttributes() to
buildContextHierarchyMap() within ContextLoaderUtils.

Issue: SPR-11011
Backport-Commit: 7658d856ca
2013-10-21 20:51:36 +02:00
Phillip Webb 5d8aa635c6 Propagate EvaluationContext from LiteralExpression
Update getValue(EvaluationContext context, Object rootObject,
Class<T> desiredResultType) to propagate the EvaluationContext to
ExpressionUtils.

Issue: SPR-10953
(cherry picked from 686cd79)
2013-10-18 17:57:46 -07:00
Juergen Hoeller ad9049e68a Polishing 2013-10-17 22:19:17 +02:00
Juergen Hoeller b9135788b9 Fixed type prediction for generic factory methods
We're consistently resolving class names now, and the entire algorithm moved from GenericTypeResolver to the internal AutowireUtils helper in the bean factory package.

Issue: SPR-10411
(cherry picked from commit 8b1927f)
2013-10-17 21:46:59 +02:00
Juergen Hoeller b62652aca1 Reduced "getParameterType call not supported" log message to single line
Issue: SPR-10185
(cherry picked from commit 41f041e)
2013-10-17 21:09:11 +02:00
Juergen Hoeller fce02d94b8 Changed JSR-330 detection logging from info to debug
Issue: SPR-10974
(cherry picked from commit 7a9d583)
2013-10-17 21:07:44 +02:00
Phillip Webb 2dca5b6815 Filter source @Configuration with @ComponentScan
Exclude self @Component when parsing @ComponentScan annotations.

Issue: SPR-10531
(cherry picked from d91ffb)
2013-10-10 17:03:36 -07:00
Juergen Hoeller a302c4ac45 Polishing
(cherry picked from commit 52cca48)
2013-10-04 23:31:18 +02:00
Rossen Stoyanchev 507cf8ad14 Make method in RequestMappingHandlerMapping protected
Issue: SPR-10950
2013-10-02 17:50:16 -04:00
Phillip Webb 7500caea52 Fix ArrayStoreException reading subclassed enums
Fix ASM AnnotationAttributesReadingVisitor to correctly deal with
subclasses enums.

Issue: SPR-10914
(cherry picked from 8abe949)
2013-09-27 11:39:11 -07:00
Juergen Hoeller 7994b63c13 Polishing 2013-09-26 21:38:54 +02:00
Juergen Hoeller 26e697b60c Silently swallow IllegalStateException on commit if the JMS transaction is based on a JDBC transaction
This fine-tuned change restores the original Spring 3.0 behavior for Oracle AQ, and also allows for other ConnectionFactory types to comply with the "getDataSource()" pattern.

Issue: SPR-10829
(cherry picked from commit 11d20e3)
2013-09-26 21:25:48 +02:00
Juergen Hoeller ef66708aa6 Fixed BadSqlGrammarException usage in transaction test suite
Issue: SPR-10902
2013-09-25 13:47:15 +02:00
Juergen Hoeller 30b3e24a32 Removed S0 from BadSqlGrammarException codes
S0 doesn't seem to be universally used for SQL grammar problems: see MS SQL Server's RAISERROR. This was reported years back; not sure why the fix didn't actually appear in the codebase back then.

Issue: SPR-10902
(cherry picked from commit d9b6203)
2013-09-25 13:05:06 +02:00
Juergen Hoeller 0a31892475 Fixed handling of @Resource's shareable value
Issue: SPR-10931
(cherry picked from commit 7bc3e3b)
2013-09-25 13:04:50 +02:00
Fedor Bobin 6fb2c72a55 Allow cursor returns from SQL functions
Update CallMetaDataContext to use the metaDataProvider
createDefaultOutParameter method when creating a SqlOutParameter as
a result of a SQL function call.

This change allows Spring to support Oracle cursor types when returned
from functions.

Issue: SPR-10606
(cherry picked from c16b21)
2013-09-24 16:09:09 -07:00
Phillip Webb c82d701a4e Fix typo in MVC reference documentation
Fix ContentNeogitatingViewResolver typo in MVC reference documentation.

Issue: SPR-10927
(cherry picked from 371d25)
2013-09-23 16:05:50 -07:00
Clément Plantier d66cf0c32f Fix "Problem locating method" SpEL error message
Replace "Problem locating method {0} cannot on type {1}" with
"Problem locating method {0} on type {1}".

Issue: SPR-10928
(cherry picked from 824ac5)

Conflicts:
	spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java
2013-09-20 11:50:30 -07:00
Juergen Hoeller 562c323989 EhCacheFactoryBean calls addCache after listener registration
Issue: SPR-10904
(cherry picked from commit a3df311)
2013-09-14 15:41:01 +02:00
Juergen Hoeller 13a68c6060 AbstractBeanFactory removes alreadyCreated entry after bean creation failure
Issue: SPR-10896
(cherry picked from commit e213561)
2013-09-14 15:37:41 +02:00
Juergen Hoeller 6110919842 Polished exception message 2013-09-04 22:11:11 +02:00
Juergen Hoeller c5aa0d12b0 Polishing
Issue: SPR-9495
(cherry picked from commit baa698e)
2013-09-04 22:05:47 +02:00
Juergen Hoeller 6de67cc2df Only cache resolved method when coming from ReflectiveMethodResolver
Issue: SPR-9495
(cherry picked from commit b7ff26a)
2013-09-04 22:00:32 +02:00
Juergen Hoeller b9d726fb84 Fixed EL resolution against static method with changing target class
Issue: SPR-10452
(cherry picked from commit 5e6044c)
2013-09-04 22:00:21 +02:00
Juergen Hoeller 2b57020c18 Polishing
(cherry picked from commit b25876f)
2013-09-04 21:59:37 +02:00
Juergen Hoeller 77298a19c9 Javadoc fixes
(cherry picked from commit facf31f)
2013-09-04 21:52:41 +02:00
Juergen Hoeller 55961544a7 Fixed method count in AbstractMethodMockingControl's IllegalStateException message
Issue: SPR-10885
2013-09-02 17:09:29 +02:00
Juergen Hoeller 5639aa7064 Properly handle getMethodDescriptors() null value on IBM JVM
Also internally renaming SimpleNonIndexedPropertyDescriptor to SimplePropertyDescriptor and preferring direct field access wherever possible.

Issue: SPR-10862
2013-09-02 16:42:06 +02:00
Juergen Hoeller 0c30618ae8 Fixed getCachedExecutor race condition in MethodReference
This commit includes a full backport of the changes in SPR-10657, instead of just the initial commit which the original backport request referred to.

Issue: SPR-10884
Issue: SPR-10657
2013-09-02 15:33:15 +02:00
Juergen Hoeller 9317d8f43e Polishing
(cherry picked from commit caa1218)
2013-08-29 19:21:24 +02:00
Juergen Hoeller 692908b722 Javadoc fixes
(cherry picked from commit 465e629)
2013-08-29 19:20:54 +02:00
Grzegorz Rożniecki c890d1e69d Fix malformed code in documentation
Fixed code snippets in "Handling complex types for stored procedure
calls" paragraph.

Issue: SPR-10798
(cherry picked from commit 00c744b)
2013-08-28 14:28:21 -07:00
clemp6r 4c7cb858d2 Fix elvis operator mistake in reference docs
In the given example the expression using the Elvis operator will
return "Nikola Tesla" and not "Mike Tesla".

Issue: SPR-10850
(cherry picked from commit 84242f1)
2013-08-28 14:17:34 -07:00
Juergen Hoeller 5a49d657d8 AnnotationConfigWebApplicationContext allows for repeated register/scan calls
Restoring consistency with AnnotationConfigApplicationContext.

Issue: SPR-10852
(cherry picked from commit 01b8d93)
2013-08-28 00:24:22 +02:00
Juergen Hoeller 8a1ae53166 Consistent use of Class<?>
(cherry picked from commit 091712d)
2013-08-28 00:23:58 +02:00
Juergen Hoeller 0765a05434 Marked @Profile as @Documented
(cherry picked from commit e812b6c)
2013-08-28 00:20:52 +02:00
Rossen Stoyanchev 072e5e8471 Revise use of FilterChain in MockMvc
MockFilterChain should not be re-used across requests. This is not an
issue unless tests are executed concurrently. This change ensures the
MockFilterChain is re-created for each request in MockMvc.

Issue: SPR-10838
2013-08-27 11:45:46 -04:00
Gabriel Axel a17912d19e Fix NPE in ResourceHttpMessageConverter
ResourceHttpMessageConverter tries to use the filename to determine the
media type, but for Resource implementations such as ByteArrayResource
it is null, which causes NullPointerException. The fix checks whether
getFilename returns null before attempting to determine the media type
by it.

Issue: SPR-10848
2013-08-22 16:14:03 -04:00
Juergen Hoeller 610e7796d9 GenericTypeResolver properly handles bound parameterized type
Issue: SPR-10819
(cherry picked from commit ea6525f)
2013-08-20 19:41:00 +02:00
Arjen Poutsma 8efac21c2b Support 'empty' StreamSource in Jaxb2Marshaller
Added support for StreamSources that do not have a InputStream or
Reader, but do have a System ID.

Issue: 10828
2013-08-13 18:16:42 -04:00
Lonre Wang 40c7303702 Fix typo in reference docs
(cherry picked from 5549bd90)
2013-08-12 14:26:08 -07:00
Arjen Poutsma c00782a3e8 Added reference to CatchAllConverter
Added reference to CatchAllConverter in both javadoc and reference docs.

Issue: SPR-10821
2013-08-12 12:32:23 +02:00
Arjen Poutsma 96f5314df6 Added XStream CatchAllConverter
Added XStream CatchAllConverter that supports all classes, but throws
exceptions for (un)marshalling.

Main purpose of this class is to register this converter as a catchall
last converter with a normal or higher priority in addition to
converters that explicitly  support the domain classes that should be
supported. As a result, default XStream  converters with lower
priorities and possible security vulnerabilities do not get invoked.

Issue: SPR-10821
2013-08-09 09:38:51 -04:00
Rossen Stoyanchev 2b628a1a0d Fix bug that ignored custom json prefix
Issue: SPR-10817
2013-08-08 09:39:08 -04:00
Spring Buildmaster 349143864c Increment version to 3.2.5.BUILD-SNAPSHOT 2013-08-06 16:15:25 -07:00
Spring Buildmaster fc73f6bb2c Release version 3.2.4.RELEASE 2013-08-06 16:00:04 -07:00
Phillip Webb 119364f326 Further 3.2.4 changelog entries 2013-08-06 15:11:43 -07:00
Arjen Poutsma 434735fbf6 Fix potential security risk when using Spring OXM
Disable by default external entity resolution when using Spring OXM
with jaxb. This prevents a XML entity from being able to resolve a
local file on the host system.

See:
https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Processing

Issue: SPR-10806
(cherry picked from commit 7576274)
2013-08-06 15:10:05 -07:00
Grzegorz Rożniecki 8f4221deb3 Fix SimpleJdbcCall and SimpleJdbcInsert Javadoc
Change "fluid" interface to "fluent" and "string" to "chain", plus fix
few typos in Javadoc.

Issue: SPR-10792
(cherry picked from commit 2344412)
2013-08-06 14:44:01 -07:00
Juergen Hoeller 2d646ca79e Polishing 2013-08-06 01:58:46 +02:00
Juergen Hoeller 1245919331 Polishing 2013-08-06 01:15:17 +02:00
Juergen Hoeller bcbd338fe2 Further 3.2.4 changelog entries 2013-08-06 00:32:59 +02:00
Juergen Hoeller 945463b826 Added javadoc note on the use of CachingConnectionFactory
Issue: SPR-10581
(cherry picked from commit 2626a35)
2013-08-06 00:31:18 +02:00
Juergen Hoeller 3ba3dd61d1 Consistent use of varargs; deprecated setAnnotatedClass method
Issue: SPR-10421
2013-08-06 00:31:06 +02:00
Juergen Hoeller cd523c7051 Restored overridable getXStream() method in Spring Framework 3.2.x
Also setting the bean class loader on the XStream instance itself now.

Issue: SPR-10421
2013-08-05 23:05:15 +02:00
Juergen Hoeller 20ddd3254b DelegatingFilterProxy avoids synchronization for pre-resolved delegate
Issue: SPR-10413
(cherry picked from commit c26272c)
2013-08-05 22:24:58 +02:00
Juergen Hoeller e30b842316 Fixed ClassFilterAwareUnionMethodMatcher equals implementation
Issue: SPR-10604
(cherry picked from commit f329140)
2013-08-05 22:23:10 +02:00
Rossen Stoyanchev b0675c031e Make date methods in HttpHeaders public
Issue: SPR-10713
2013-08-05 12:46:33 -04:00
Rossen Stoyanchev 0f71da5be6 Return -1 after parse error for Expires header
Issue: SPR-10648
2013-08-05 12:38:53 -04:00
Juergen Hoeller 9035a97e18 Refined javadoc for WebLogic/WebSphere transaction setup
Issue: SPR-10777
2013-08-01 17:24:24 +02:00
Juergen Hoeller d32a77a5f0 Optimized TomcatInstrumentableClassLoader implementation
Issue: SPR-10788
2013-08-01 15:49:58 +02:00
Juergen Hoeller d8e3ef7640 Polishing
Issue: SPR-10752
Issue: SPR-10627
2013-08-01 00:35:51 +02:00
Juergen Hoeller ccb02a2355 Updated changelog for 3.2.4 2013-07-31 23:42:36 +02:00
Juergen Hoeller d0948f1f03 Fixed misunderstanding with respect to excludeUnlistedClasses default in JPA 2.0
Issue: SPR-10767
2013-07-31 23:40:59 +02:00
Juergen Hoeller ae0f23e942 Polishing
Issue: SPR-10752
Issue: SPR-10627
2013-07-31 22:42:27 +02:00
Juergen Hoeller b40263e06b PropertySourcesPlaceholderConfigurer's "ignoreUnresolvablePlaceholders" setting reliably applies to nested placeholders as well
Issue: SPR-10549
(cherry picked from commit 127b91f)
2013-07-31 18:38:31 +02:00
Juergen Hoeller 2f8dfb3e52 Updated Quartz version range in javadoc
Issue: SPR-10775
2013-07-30 23:27:34 +02:00
Juergen Hoeller d5c78c953d Remove the JobDetail from the job data map after discovering it
Issue: SPR-10775
2013-07-30 23:27:33 +02:00
Juergen Hoeller dfac1d0510 Added "requestsRecovery" bean property to JobDetailFactoryBean
Issue: SPR-10775
2013-07-30 23:27:32 +02:00
Juergen Hoeller 14b83c3fcc Polishing
Issue: SPR-10609
2013-07-30 23:27:30 +02:00
Phillip Webb ae6e84bc7d Fix TestNG build settings 2013-07-30 14:21:28 -07:00
Phillip Webb 4213a31a7d Fix failing test due to CUSTOM_COMPILATION Group 2013-07-30 13:54:42 -07:00
Phillip Webb 22454c8edf Upgradle to gradle 1.6 2013-07-30 13:29:05 -07:00
Deline Neo 98da5a7b2b Add attributeDoesNotExist ModelResultMatcher
Issue: SPR-10509
2013-07-30 15:41:55 -04:00
Phillip Webb 0a37552beb Add CUSTOM_COMPILATION TestGroup 2013-07-30 11:54:22 -07:00
Phillip Webb 1b702fa6a2 Revert "Add test source dependency in attempt to fix CI"
This reverts commit a2e438b2be.
2013-07-30 11:53:34 -07:00
Phillip Webb a2e438b2be Add test source dependency in attempt to fix CI 2013-07-30 11:33:30 -07:00
Phillip Webb 9ff9d45283 Minor polish to gradle build 2013-07-30 10:33:52 -07:00
Phillip Webb 1fee4c0c0b Upgradle to gradle 1.6 2013-07-30 10:33:03 -07:00
Rossen Stoyanchev dc87a2211c Make HTTP scheme parsing case-insensitive
Issue: SPR-10779
2013-07-30 12:33:22 -04:00
Phillip Webb 77b7344530 Upgradle to gradle 1.6 2013-07-30 09:29:44 -07:00
Phillip Webb 7cde4f1503 Update gradle plugin versions 2013-07-30 09:22:08 -07:00
Rossen Stoyanchev 6c11fd3b5e Fix issue with parsing x-forwarded-host header
Issue: SPR-10701
2013-07-30 11:48:06 -04:00
Biju Kunjummen eec4a37d1c Fix Jaxb2TypeScanner to scan for @XmlRegistry
Update ClassPathJaxb2TypeScanner to scan for @XmlRegistry classes.

Prior to this commit explicitly configured @XmlRegistry annotated classes
were not registered with the JAXBContext when using the 'packagesToScan'
property of the Jaxb2Unmarshaller.

Issue: SPR-10714
(cherry picked from 4f871d4)
2013-07-29 11:26:52 -07:00
Phillip Webb 1e3dc4aeae Include argument types in MethodReference cache
Update the cached MethodExecutor in MethodReference to include the
method argument types. Prevents the incorrect use of the cache when the
SpEL expression refers to a class that has overloaded methods.

Issue: SPR-10657
(cherry picked from commit f9b12b8)
2013-07-25 11:28:03 +02:00
Phillip Webb d4b54d834e Skip abstract beans in getBeansWithAnnotation()
Update BeanFactory.getBeansWithAnnotation() to skip any abstract
bean definitions.

Issue: SPR-10663
(cherry picked from commit 8ed8ee2)
2013-07-25 11:27:57 +02:00
Juergen Hoeller 3562cd759b Moved executor null check to AsyncExecutionInterceptor, allowing AbstractAsyncExecutionAspect to fall back to sync execution (as in 3.2.1)
Issue: SPR-10636
(cherry picked from commit b6c54c3)
2013-07-25 10:45:59 +02:00
Juergen Hoeller c1dc4e2c75 Resource-based PlatformTransactionManager implementations defensively catch Throwable in doBegin in order to reliably close resource in case of OutOfMemoryError
Issue: SPR-10755
(cherry picked from commit 2e4eb9f)
2013-07-25 10:45:58 +02:00
Phillip Webb 8feeec4a60 Fix ResourceHttpRequestHandler empty location log
Fix ResourceHttpRequestHandler to only log warning when locations
is empty.

Issue: SPR-10780
(cherry picked from bc52469)
2013-07-24 16:52:47 -07:00
Phillip Webb 440a63a3d0 Make TypeDescriptor serializable
Issue: SPR-10631
(cherry picked from 9eb596a)
2013-07-23 14:19:15 -07:00
Phillip Webb 274ed1fe67 Remove unnecessary spring-instrument dependencies
Remove unnecessary spring-core dependency from spring-instrument.

Issue: SPR-10732
(cherry picked from 9939c48)
2013-07-23 13:37:43 -07:00
Phillip Webb 1b47f6c0b0 Add Java 7 instrumentation manifest attributes
Update META-INF/MANIFEST.MF for spring-instrument to include
necessary attributes for running under Java 7:

    Can-Redefine-Classes : true
    Can-Retransform-Classes: true
    Can-Set-Native-Method-Prefix : false

(see http://docs.oracle.com/javase/7/docs/api/java/lang/instrument/
package-summary.html)

Prior to this commit `InstrumentationSavingAgent.getInstrumentation().
addTransformer(t, true);` would fail under Java 7.

Issue: SPR-10731
(Cherry picked from 50333ca)
2013-07-23 13:37:09 -07:00
Phillip Webb 66e4c9b2bb Fix case of rollbackForClassName in ref docs
Update @Transactional reference documentation to fix the case of the
rollbackForClassName and noRollbackForClassName attributes.

Issue: SPR-10754
(cherry picked from 1204d2a)
2013-07-22 15:48:27 -07:00
Nick Williams e608055021 Parse JPA <exclude-unlisted-classes> correctly
Fix PersistenceUnitReader to correctly read <exclude-unlisted-classes>
in both JPA 1.0 and 2.0 persistence.xml files.

Prior to this commit PersistenceUnitReader would set the value of
excludeUnlistedClasses to true when a <exclude-unlisted-classes> element
was present, regardless of its value.

The following rules are now used when parsing:

- If the <exclude-unlisted-classes> element is missing the appropriate
  default value is set (based on the JPA version).

- If an empty <exclude-unlisted-classes/> element is found the
  excludeUnlistedClasses property is set to true.

- Otherwise the value of the <exclude-unlisted-classes> element is used
  to set the excludeUnlistedClasses property.

Issue: SPR-10767
(cherry picked from 7ad540d)

Conflicts:
	spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceUnitReader.java
2013-07-22 12:38:46 -07:00
Phillip Webb 199be0ad3c Add spring-core cglib dependency 2013-07-19 14:52:54 -07:00
Phillip Webb af7753eac6 Add MemorySafeUndeclaredThrowableStrategy
Port the latest unreleased UndeclaredThrowableStrategy implementation
from cglib to fix a memory-leak present in v3.

Issue: SPR-10709
(cherry picked from 587877c)
2013-07-19 14:39:24 -07:00
Rossen Stoyanchev cce74b8ba2 Make the JSON prefix used in converters configurable
Issue: SPR-10627
2013-07-19 17:23:33 -04:00
Rossen Stoyanchev dd7508d606 Replace assert w/ warning in ResourceHttpRequestHandl.
Issue: SPR-9186
2013-07-19 17:23:33 -04:00
Rossen Stoyanchev 3bf56dda56 Fix issue in MappingJacksonJsonView
Issue: SPR-10752
2013-07-19 17:23:33 -04:00
Phillip Webb a72209aad3 Make ConfClassPostPro Ordered.HIGHEST_PRECEDENCE
Make ConfigurationClassPostProcessor Ordered.HIGHEST_PRECEDENCE in
case several BeanDefinitionRegistryPostProcessors are registered.

Issue: SPR-10645
(cherry picked from 350cb9b)
2013-07-19 14:16:39 -07:00
Phillip Webb 67f41b15eb Resolve ${} placeholders in @ImportResource
Update ConfigurationClassParser to resolve any ${} placeholders from
@ImportResource values.

Issue: SPR-10686
(cherry picked from commit 700a08e)
2013-07-19 13:14:05 -07:00
Arjen Poutsma 3515acfa3d Added 'processExternalEntities' to JAXB2Marshaller
Added 'processExternalEntities' property to the JAXB2Marshaller, which
indicates whether external XML entities are processed when
unmarshalling.

Default is false, meaning that external entities are not resolved.
Processing of external entities will only be enabled/disabled when the
Source} passed to #unmarshal(Source) is a SAXSource or StreamSource. It
has no effect for DOMSource or StAXSource instances.
2013-07-19 11:07:07 -04:00
Rossen Stoyanchev 7fdd0c22b2 Fix issue in ContentNeogitatingViewResolver
The following commit in 3.2.3 had a side effect on CNVR:
https://github.com/SpringSource/spring-framework/commit/aaded7e30b06cc70a354856a2288acd04045b673

It appears that CNVR doesn't treat a request for "*/*" differently
from a request that does not request content types. Both should be
interpreted as "any content type is acceptable". This fix ensures
that CNVR treats these two cases the same way.

Issue: SPR-10683
2013-07-18 22:03:13 -04:00
Rossen Stoyanchev a0f8a894f2 Cache constructor instance in WebAsyncUtils
Issue: SPR-10673
2013-07-18 17:48:18 -04:00
Phillip Webb 55f02db18e 'Rename' HttpHeaders.getIfNotModifiedSince()
Effectively rename HttpHeaders.getIfNotModifiedSince() to
getIfModifiedSince() by adding a new method and deprecating the
old one.

Issue: SPR-10600
2013-06-26 10:45:33 -07:00
Phillip Webb 71e88cbf30 Fix SQL syntax error in jdbcTemplate update docs
Update the reference guide jdbcTemplate update example to include the
column name.

Issue: SPR-10625
2013-06-25 22:22:36 -07:00
Phillip Webb 514a2e9568 Package RmiInvocationWrapperRTD.xml in jar
Ensure RmiInvocationWrapperRTD.xml is packaged inside spring-context.jar

Issue: SPR-10649

Conflicts:
	build.gradle
2013-06-23 23:52:05 -07:00
Rossen Stoyanchev abfb439bfe Reverse SPR-10402 change that caused 3.2.3 regression
SPR-10402 in Spring Framework 3.2.3 treated empty request parameter
values as missing values, if the empty value was turned into a null
by a PropertyEditor or Converter. This caused the regression.

Issue: SPR-10578, SPR-10402, SPR-10584
2013-06-20 16:25:30 -04:00
Phillip Webb 4ba43b4737 Support meta @Component with non-string value
Update AnnotationBeanNameGenerator to only use the value attribute of
a @Component meta-annotated annotation when it is a String.

Issue: SPR-10580
2013-06-04 10:24:14 -07:00
Spring Buildmaster 2655657a51 2013-05-20 10:18:53 -07:00
Rob Winch 404671416a Update BuildTests to verify JDK 1.6
Issue: SPR-10569
2013-05-20 10:37:33 -05:00
Phillip Webb 260eafc819 Enforce JDK version on CI server
Add a test to ensure that the CI server does not accidentally build
with the wrong JDK version.

Issue: SPR-10569
2013-05-16 17:14:03 -07:00
Juergen Hoeller ef8b5763e6 Final addition to 3.2.3 changelog 2013-05-16 19:31:57 +02:00
Juergen Hoeller 6b89af824d Consistent detection of Order annotation in superclasses and interfaces
Issue: SPR-10514
(cherry picked from commit 814d24e)
2013-05-16 18:07:00 +02:00
Juergen Hoeller 86b4b2ef23 Consistent use of Class<?> in Assert
(cherry picked from commit 16548d2)
2013-05-16 16:11:30 +02:00
Juergen Hoeller faa8430fd7 Avoid NPE in ContextLoader when dealing with an untyped ApplicationContextInitializer
Issue: SPR-10449
(cherry picked from commit a19c976)
2013-05-16 16:11:25 +02:00
Juergen Hoeller 76f870caca Final preparations for 3.2.3 release 2013-05-16 14:50:03 +02:00
Juergen Hoeller 615315728b Fixed BeanPropertyRowMapper to only prefix actual upper-case letters with underscores
Issue: SPR-10547
(cherry picked from commit c8b071c)
2013-05-16 14:34:44 +02:00
Juergen Hoeller 115442242f Replaced Map synchronization with ConcurrentHashMap to avoid session access deadlocks
Issue: SPR-10436
(cherry picked from commit cd3d0c3)
2013-05-16 14:34:38 +02:00
Juergen Hoeller 10c0e8af01 Final changelog entries for 3.2.3 2013-05-16 00:17:00 +02:00
Juergen Hoeller b6e20a4cc9 Introduced "jsonPrefix" bean property
This change involves a modification of the "writeContent" template method to include the "jsonPrefix" String instead of the "prefixJson" boolean flag. Since said template method has only been introduced in 3.2.2, this change should hopefully not be a problem.

Issue: SPR-10567
(cherry picked from commit 28164b4)
2013-05-16 00:02:31 +02:00
Juergen Hoeller a8adec7673 Avoid unnecessary creation of default StandardEnvironment instances
Issue: SPR-10568
(cherry picked from commit 7e01578)
2013-05-15 23:59:29 +02:00
Juergen Hoeller 2ae61c503e Further changelog entries for 3.2.3 2013-05-15 17:04:34 +02:00
Juergen Hoeller c2b2f30669 Polishing 2013-05-15 16:57:57 +02:00
Juergen Hoeller 239a7cd85f Fixed type detection to avoid reuse of parent bean's targetType on child definition merge
Issue: SPR-10374
(cherry picked from commit 070103b)
2013-05-15 16:42:28 +02:00
Juergen Hoeller 6e4317ebfb Properly handle knownSuperclasses in case of an overridden ConfigurationClass
Issue: SPR-10546
2013-05-15 13:47:03 +02:00
Juergen Hoeller 325d8834e3 Polishing 2013-05-15 11:34:58 +02:00
Juergen Hoeller 0c76cb7e80 Clarified that CronTrigger never schedules overlapping executions
Issue: SPR-10556
(cherry picked from commit 5dbbd8f)
2013-05-15 11:34:57 +02:00
Rob Winch 940011e233 Ensure Parent ConfigurationClass loaded on overrides
Previously ConfigurationClassParser could override a nested
@Configuration without consideration of @Bean's defined in parent
classes.

This commit ensures that if the original ConfigurationClass contains
additional bean definitions it is processed again.

Issue: SPR-10546
2013-05-15 11:34:56 +02:00
Rossen Stoyanchev 92bbd8103b Make removal of jsessionid case insensitive
Issue: SPR-10398
2013-05-14 22:07:52 -04:00
Rossen Stoyanchev 9c194699c7 Reinstate removal of semicolon content
Commit 5b1165 was an attempt to leave semicolon content in the URL path
while ignoring it for request mapping purposes. However, it becomes
quite difficult to manage and semicolon content should not always be
ignored (sometimes a semicolon is used as a separator of multiple items
in a path segment, rather than for matrix variables).

This change effectively reverts back to the original approach in 3.2
where a flag on AbstractHandlerMapping can be used to have semicolon
content removed or kept. If kept, path segments with matrix variables
must be represented with a path segment.

The main difference is that by default it is removed everywhere
including the MVC namespace and Java config.

Issue: SPR-10427, SPR-10234
2013-05-14 21:30:59 -04:00
Rossen Stoyanchev 25701ef984 Fix deadlock issue in DeferredResult
Previously DeferredResult locked around the setting of the result
including handling up to the part of submitting a dispatch. This
can cause a deadlock if a timeout occurs at the same time since
the Tomcat timeout thread has its own locking that permits only
one thread to do timeout or dispatch processing.

The fix reduces the locking to cover only the attempt to set the
DeferredResult but not the dispatching.

Issue: SPR-10485
2013-05-14 17:06:00 -04:00
Juergen Hoeller 87ef99df5e Updated changelog for 3.2.3 release 2013-05-14 18:50:39 +02:00
Juergen Hoeller 13ca2752ae Consistent use of Class<?> in core container method signatures
(cherry picked from commit 1461744)
2013-05-14 18:06:12 +02:00
Juergen Hoeller ef363b0f7a Detect a FactoryBean type match even if predictBeanType returned a non-FactoryBean type
This change should be the final piece in the puzzle to let SmartInstantiationAwareBeanPostProcessor's predictBeanType predict a FactoryBean-produced type, effectively as a semantic alternative to its postProcessBeforeInstantiation-related role.

Issue: SPR-10517
(cherry picked from commit bc3e585)
2013-05-14 18:02:49 +02:00
Juergen Hoeller f9db59e730 GenericTypeResolver defensively calls Class.getGenericSuperclass() and consistently uses Class<?>
Issue: SPR-10559
(cherry picked from commit 25e29b8)
2013-05-14 18:01:41 +02:00
Rob Winch 0dcca2304f Remove xdoclint:none for < JDK 8 2013-05-13 11:54:58 -05:00
Rossen Stoyanchev ad272a0c87 Close InputStream in ResourceHttpMessageConverter
Spring 3.2.2 introduced a change to avoid closing the response stream
in HttpMessageConverters (SPR-10095). However, the InputStream of
resources being written, for example as part of a multi-part request
should be closed. This change ensures that.

Issue: SPR-10460
2013-05-10 17:31:48 -04:00
Juergen Hoeller be224e1f30 ServletContextResourcePatternResolver uses encoded jar file location for UrlResource
Adding overloaded constructors for URI specification to UrlResource, as a convenience.

Issue: SPR-10471
(cherry picked from commit 1f0f46f)
2013-05-10 22:13:17 +02:00
Rossen Stoyanchev 4bb0916202 Delay check if pattern ends with slash
This is a minor fix with no actual impact.

Issue: SPR-10504
2013-05-10 12:51:48 -04:00
Rossen Stoyanchev d3eda09c01 Allow treating empty @RequestParam as missing value
If type conversion turns an empty request parameter value (i.e. "") to
null, we should treat it as a missing value. By default the
ConversionService doesn't change empty strings and therefore one must
explicitly convert them to null for example by registering a
StringTrimmerEditor with emptyAsNull=true.

Issue: SPR-10402
2013-05-10 12:51:31 -04:00
Rossen Stoyanchev 399f887128 Add servletRelativeAction form tag attribute
A recent change in FormTag to prepend the context and servlet paths if
not present, causes issues when used in portlet applications.
This change introduces a servletRelativeAction form tag attribute that
must be used for the context and servlet paths to be prepended.

Issue: SPR-10382
2013-05-10 12:51:20 -04:00
Rossen Stoyanchev 4d005b6987 Improve default content type selection
Previously ContentNegotiationManager continued with the next
ContentNegotiationStrategy only if the current one returned an empty
list. Now it also does that if the current ContentNegotiationStrategy
returns "*/*". Since the absence of an Accept header and "*/*" have
the same meaning, this allows a default content type to be used in
either case.

Issue: SPR-10513
2013-05-10 12:51:08 -04:00
Rossen Stoyanchev 532a7a3a02 Invoke global, then local @InitBinder/@ModelAttribute
@InitBinder and @ModelAttribute methods in @ControllerAdvice classes
are now invoked first, allowing any such methods in the @Controller
class to override them.

Issue: SPR-10419
2013-05-10 12:50:24 -04:00
Juergen Hoeller b2d416fd5f Revised ReflectiveMethodResolver to properly handle any kind of List returned from a MethodFilter
Issue: SPR-10392
(cherry picked from commit ad88650)
2013-05-07 22:07:29 +02:00
Juergen Hoeller 7298c3d669 Fixed MockMvc example code
Issue: SPR-10389
(cherry picked from commit 35847ad)
2013-05-07 22:06:51 +02:00
Juergen Hoeller 7bbd38b9e0 Fixed javadoc warnings
Issue: SPR-10373
(cherry picked from commit 1ca943c)
2013-05-07 22:06:33 +02:00
Juergen Hoeller 64d83a550e MappingJackson(2)MessageConverter needs to use bean ClassLoader 2013-05-07 18:22:48 +02:00
Juergen Hoeller 0df1630ab9 Jaxb2Marshaller doesn't need to depend on ResourceLoaderAware
Issue: SPR-10512
(cherry picked from commit 255eab5)
2013-05-03 17:48:12 +02:00
Juergen Hoeller 7cbc115da6 Added "postProcessConfiguration" template method to LocalValidatorFactoryBean; clarified limited compatibility with Hibernate Validator 5.0 2013-05-03 15:19:28 +02:00
Juergen Hoeller b962239e11 Polishing 2013-05-03 13:47:54 +02:00
Juergen Hoeller 872cf6b076 Removed unnecessary HttpUrlTemplate subclass of UriTemplate 2013-05-03 13:38:31 +02:00
Juergen Hoeller b2bd319d47 Polished UriComponents implementation
(cherry picked from commit c3b624d)
2013-05-03 13:23:48 +02:00
Juergen Hoeller e3fa49063e Added note on non-thread-safety of Jackson's DateFormat support 2013-05-02 16:06:51 +02:00
Juergen Hoeller c302efdbbf Further build file updates for alignment with 4.0 build 2013-05-01 22:38:43 +02:00
Juergen Hoeller 12699696f4 Added note on OpenJDK 8 compatibility 2013-05-01 21:45:50 +02:00
Juergen Hoeller c4f2566070 Allow for building and testing the 3.2.x line against OpenJDK 8 2013-05-01 21:39:51 +02:00
Juergen Hoeller 6458643f15 Updated 3.2.3 changelog 2013-04-30 23:57:15 +02:00
Juergen Hoeller 2145545e69 Ignore failing TopLink tests (not worth messing with since TopLink is deprecated anyway) 2013-04-30 23:29:07 +02:00
Juergen Hoeller f6545cde38 Polishing 2013-04-30 23:29:06 +02:00
Juergen Hoeller 601c64a65c Removed broken applyQueryTimeout implementation (following a fix in 4.0) 2013-04-30 23:29:06 +02:00
Juergen Hoeller 964f1a6213 Refined HibernateJpaDialect for Hibernate 4.2 support
HibernateJpaDialect's HibernateConnectionHandle does not call close() for Hibernate 4.x anymore, since on 4.2, the exposed Connection handle isn't a "borrowed connection" wrapper but rather the actual underlying Connection - with a close() call immediately returning the Connection to the pool and making the local handle invalid for further use within the transaction.

Issue: SPR-10395
2013-04-30 23:29:05 +02:00
Juergen Hoeller 886cc2cce8 Fixed general test suite problems found during OpenJDK 8 upgrade
Issue: SPR-9639
(cherry picked from commit 19f783b)
2013-04-30 23:29:04 +02:00
Juergen Hoeller 5bdd2d245c Consistent Map/Set ordering
Use LinkedHashMaps/Sets wherever exposed to users, and code tests defensively in terms of expected Map/Set ordering. Otherwise, there'll be runtime order differences between JDK 7 and JDK 8 due to internal HashMap/Set implementation differences.

Issue: SPR-9639
(cherry picked from commit 9c09a0a)
2013-04-30 23:29:03 +02:00
Juergen Hoeller d0513f7521 Revised Joda-Time support (as a side effect of JSR-310 support in Spring 4.0)
Issue: SPR-9641
(cherry picked from commit b5d44e1)
2013-04-30 23:29:02 +02:00
Juergen Hoeller 265c0c1505 Minimized ASM usage
In particular, avoid accidental usage of ASM for core JDK types - which will fail in case of a new bytecode version in the JDK, even if the application itself has been compiled with an earlier bytecode target.

Issue: SPR-10292
(cherry picked from commit d3a4068)
2013-04-30 23:29:02 +02:00
Juergen Hoeller 886cf825cb Added "getName()" accessor to MethodReference
Issue: SPR-10422
(cherry picked from commit 5ff2653)
2013-04-30 23:29:01 +02:00
Juergen Hoeller 03033f6c06 Fixed typo in code example
Issue: SPR-10394
(cherry picked from commit f374b7a)
2013-04-30 23:29:00 +02:00
Juergen Hoeller 5ff2dfbe13 Removed references to deprecated queryForInt method from documentation
Issue: SPR-10257
(cherry picked from commit 6be954e)
2013-04-30 23:28:59 +02:00
Juergen Hoeller fa44ab6336 Removed unnecessary CGLIB 2.2 dependency from spring-test-mvc module
(cherry picked from commit 657bd80)
2013-04-30 23:28:58 +02:00
Juergen Hoeller eed1a58b81 Fixed annotation attribute processing for enum arrays
Based on https://github.com/SpringSource/spring-framework/pull/263
(cherry picked from commit 06fdfb0)
2013-04-30 23:28:57 +02:00
10404 changed files with 439813 additions and 942854 deletions
-10
View File
@@ -1,10 +0,0 @@
root = true
[*.{adoc,bat,groovy,html,java,js,jsp,kt,kts,md,properties,py,rb,sh,sql,svg,txt,xml,xsd}]
charset = utf-8
[*.{groovy,java,kt,kts,xml,xsd}]
indent_style = tab
indent_size = 4
continuation_indent_size = 8
end_of_line = lf
-16
View File
@@ -1,16 +0,0 @@
# Normalize line endings to LF.
* text eol=lf
# Ensure that line endings for multipart files in spring-web are not modified.
*.multipart -text
# Ensure that line endings for DOS batch files are not modified.
*.bat -text
# Ensure the following are treated as binary.
*.gif binary
*.jar binary
*.jpeg binary
*.jpg binary
*.png binary
*.vsd binary
-17
View File
@@ -1,17 +0,0 @@
<!--
!!! For Security Vulnerabilities, please go to https://spring.io/security-policy !!!
-->
**Affects:** \<Spring Framework version>
---
<!--
Thanks for taking the time to create an issue. Please read the following:
- Questions should be asked on Stack Overflow.
- For bugs, specify affected versions and explain what you are trying to do.
- For enhancements, provide context and describe the problem.
Issue or Pull Request? Create only one, not both. GitHub treats them as the same.
If unsure, start with an issue, and if you submit a pull request later, the
issue will be closed as superseded.
-->
@@ -1,13 +0,0 @@
name: "Validate Gradle Wrapper"
on: [push, pull_request]
permissions:
contents: read
jobs:
validation:
name: "Validation"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: gradle/wrapper-validation-action@v1
-16
View File
@@ -15,20 +15,11 @@ spring-test/test-output/
.gradle
argfile*
pom.xml
activemq-data/
classes/
/build
buildSrc/build
/spring-*/build
/spring-core/graalvm/build
/spring-core/kotlin-coroutines/build
/framework-bom/build
/framework-docs/build
/integration-tests/build
/src/asciidoc/build
target/
/target/
# Eclipse artifacts, including WTP generated manifests
.classpath
@@ -39,13 +30,6 @@ spring-*/src/main/java/META-INF/MANIFEST.MF
*.iml
*.ipr
*.iws
.idea
out
test-output
atlassian-ide-plugin.xml
.gradletasknamecache
# VS Code
.vscode/
cached-antora-playbook.yml
-33
View File
@@ -1,33 +0,0 @@
Juergen Hoeller <jhoeller@vmware.com>
Juergen Hoeller <jhoeller@vmware.com> <jhoeller@pivotal.io>
Juergen Hoeller <jhoeller@vmware.com> <jhoeller@gopivotal.com>
Rossen Stoyanchev <rstoyanchev@vmware.com>
Rossen Stoyanchev <rstoyanchev@vmware.com> <rstoyanchev@pivotal.io>
Rossen Stoyanchev <rstoyanchev@vmware.com> <rstoyanchev@gopivotal.com>
Phillip Webb <pwebb@vmware.com>
Phillip Webb <pwebb@vmware.com> <pwebb@pivotal.io>
Phillip Webb <pwebb@vmware.com> <pwebb@gopivotal.com>
Chris Beams <cbeams@vmware.com>
Chris Beams <cbeams@vmware.com> <cbeams@pivotal.io>
Chris Beams <cbeams@vmware.com> <cbeams@gopivotal.com>
Arjen Poutsma <apoutsma@vmware.com>
Arjen Poutsma <apoutsma@vmware.com> <apoutsma@pivotal.io>
Arjen Poutsma <apoutsma@vmware.com> <apoutsma@gopivotal.com>
Arjen Poutsma <apoutsma@vmware.com> <poutsma@mac.com>
Oliver Drotbohm <odrotbohm@vmware.com>
Oliver Drotbohm <odrotbohm@vmware.com> <ogierke@vmware.com>
Oliver Drotbohm <odrotbohm@vmware.com> <ogierke@pivotal.io>
Oliver Drotbohm <odrotbohm@vmware.com> <ogierke@gopivotal.com>
Dave Syer <dsyer@vmware.com>
Dave Syer <dsyer@vmware.com> <dsyer@pivotal.io>
Dave Syer <dsyer@vmware.com> <dsyer@gopivotal.com>
Dave Syer <dsyer@vmware.com> <david_syer@hotmail.com>
Andy Clement <aclement@vmware.com>
Andy Clement <aclement@vmware.com> <aclement@pivotal.io>
Andy Clement <aclement@vmware.com> <aclement@gopivotal.com>
Andy Clement <aclement@vmware.com> <andrew.clement@gmail.com>
Sam Brannen <sbrannen@vmware.com>
Sam Brannen <sbrannen@vmware.com> <sbrannen@pivotal.io>
Sam Brannen <sbrannen@vmware.com> <sam@sambrannen.com>
<dmitry.katsubo@gmail.com> <dmitry.katsubo@gmai.com>
Nick Williams <nicholas@nicholaswilliams.net>
-3
View File
@@ -1,3 +0,0 @@
# Enable auto-env through the sdkman_auto_env config
# Add key=value pairs of SDKs to use below
java=8.0.382-librca
@@ -0,0 +1,9 @@
#com.springsource.sts.gradle.core.preferences.GradleImportPreferences
#Thu Aug 9 11:34:43 CEST 2012
enableAfterTasks=true
afterTasks=afterEclipseImport;
enableDependendencyManagement=false
enableBeforeTasks=true
projects=;spring-aop;spring-aspects;spring-beans;spring-context;spring-context-support;spring-core;spring-expression;spring-instrument;spring-instrument-tomcat;spring-jdbc;spring-jms;spring-orm;spring-oxm;spring-struts;spring-test;spring-tx;spring-web;spring-webmvc;spring-webmvc-portlet;
enableDSLD=false
beforeTasks=cleanEclipse;eclipse;\:spring-oxm\:compileTestJava;
@@ -0,0 +1,5 @@
#com.springsource.sts.gradle.core.preferences.GradleProjectPreferences
#Tue Feb 21 14:38:31 CET 2012
com.springsource.sts.gradle.classpath.enableSorting=false
com.springsource.sts.gradle.rootprojectloc=
com.springsource.sts.gradle.linkedresources=
@@ -0,0 +1,9 @@
#com.springsource.sts.gradle.core.actions.GradleRefreshPreferences
#Thu Aug 9 11:34:43 CEST 2012
enableAfterTasks=true
afterTasks=afterEclipseImport;
useHierarchicalNames=false
enableBeforeTasks=true
addResourceFilters=false
enableDSLD=false
beforeTasks=cleanEclipse;eclipse;\:spring-oxm\:compileTestJava;
-44
View File
@@ -1,44 +0,0 @@
= Contributor Code of Conduct
As contributors and maintainers of this project, and in the interest of fostering an open
and welcoming community, we pledge to respect all people who contribute through reporting
issues, posting feature requests, updating documentation, submitting pull requests or
patches, and other activities.
We are committed to making participation in this project a harassment-free experience for
everyone, regardless of level of experience, gender, gender identity and expression,
sexual orientation, disability, personal appearance, body size, race, ethnicity, age,
religion, or nationality.
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery
* Personal attacks
* Trolling or insulting/derogatory comments
* Public or private harassment
* Publishing other's private information, such as physical or electronic addresses,
without explicit permission
* Other unethical or unprofessional conduct
Project maintainers have the right and responsibility to remove, edit, or reject comments,
commits, code, wiki edits, issues, and other contributions that are not aligned to this
Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors
that they deem inappropriate, threatening, offensive, or harmful.
By adopting this Code of Conduct, project maintainers commit themselves to fairly and
consistently applying these principles to every aspect of managing this project. Project
maintainers who do not follow or enforce the Code of Conduct may be permanently removed
from the project team.
This Code of Conduct applies both within project spaces and in public spaces when an
individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by
contacting a project maintainer at spring-code-of-conduct@pivotal.io . All complaints will
be reviewed and investigated and will result in a response that is deemed necessary and
appropriate to the circumstances. Maintainers are obligated to maintain confidentiality
with regard to the reporter of an incident.
This Code of Conduct is adapted from the
https://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at
https://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/]
+273 -101
View File
@@ -1,131 +1,303 @@
# Contributing to the Spring Framework
_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
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._
First off, thank you for taking the time to contribute! :+1: :tada:
_Please refer back to this document as a checklist before issuing any pull
request; this will save time for everyone!_
### Table of Contents
## Understand the basics
* [Code of Conduct](#code-of-conduct)
* [How to Contribute](#how-to-contribute)
* [Discuss](#discuss)
* [Create an Issue](#create-an-issue)
* [Issue Lifecycle](#issue-lifecycle)
* [Submit a Pull Request](#submit-a-pull-request)
* [Build from Source](#build-from-source)
* [Source Code Style](#source-code-style)
* [Reference Docs](#reference-docs)
### Code of Conduct
This project is governed by the [Spring Code of Conduct](CODE_OF_CONDUCT.adoc).
By participating you are expected to uphold this code.
Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
### How to Contribute
#### Discuss
If you have a question, check Stack Overflow using
[this list of tags](https://stackoverflow.com/questions/tagged/spring+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-remoting+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux?tab=Newest).
Find an existing discussion, or start a new one if necessary.
If you believe there is an issue, search through
[existing issues](https://github.com/spring-projects/spring-framework/issues) trying a
few different ways to find discussions, past or current, that are related to the issue.
Reading those discussions helps you to learn about the issue, and helps us to make a
decision.
Not sure what a pull request is, or how to submit one? Take a look at GitHub's
excellent [help documentation][] first.
#### Create an Issue
## Search JIRA first; create an issue if necessary
Reporting an issue or making a feature request is a great way to contribute. Your feedback
and the conversations that result from it provide a continuous flow of ideas. However,
before creating a ticket, please take the time to [discuss and research](#discuss) first.
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.
If creating an issue after a discussion on Stack Overflow, please provide a description
in the issue instead of simply referring to Stack Overflow. The issue tracker is an
important place of record for design discussions and should be self-sufficient.
## Discuss non-trivial contribution ideas with committers
Once you're ready, create an issue on
[GitHub](https://github.com/spring-projects/spring-framework/issues).
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.
#### Issue Lifecycle
## Sign the Contributor License Agreement
When an issue is first created, it is flagged `waiting-for-triage` waiting for a team
member to triage it. Once the issue has been reviewed, the team may ask for further
information if needed, and based on the findings, the issue is either assigned a target
milestone or is closed with a specific status.
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.
Keep track of this; you may be asked for it later!
When a fix is ready, the issue is closed and may still be re-opened until the fix is
released. After that the issue will typically no longer be reopened. In rare cases if the
issue was not at all fixed, the issue may be re-opened. In most cases however any
follow-up reports will need to be created as new issues with a fresh description.
Note that emailing/postal mailing a signed copy is _not_ necessary. Submission
of the web form is all that is required.
#### Submit a Pull Request
Once you've completed the web form, simply add the following in a comment on
your pull request:
1. If you have not previously done so, please sign the
[Contributor License Agreement](https://cla.pivotal.io/sign/spring). You will be reminded
automatically when you submit the PR.
I have signed and agree to the terms of the SpringSource Individual
Contributor License Agreement.
1. Should you create an issue first? No, just create the pull request and use the
description to provide context and motivation, as you would for an issue. If you want
to start a discussion first or have already created an issue, once a pull request is
created, we will close the issue as superseded by the pull request, and the discussion
about the issue will continue under the pull request.
You do not need to include your token/id. Please add the statement above to all
future pull requests as well, simply so that the Spring Framework team knows
immediately that this process is complete.
1. Always check out the `main` branch and submit pull requests against it
(for target version see [settings.gradle](settings.gradle)).
Backports to prior versions will be considered on a case-by-case basis and reflected as
the fix version in the issue tracker.
1. Choose the granularity of your commits consciously and squash commits that represent
multiple edits or corrections of the same logical change. See
[Rewriting History section of Pro Git](https://git-scm.com/book/en/Git-Tools-Rewriting-History)
for an overview of streamlining the commit history.
## Create your branch from `3.2.x`
1. Format commit messages using 55 characters for the subject line, 72 characters per line
for the description, followed by the issue fixed, e.g. `Closes gh-22276`. See the
[Commit Guidelines section of Pro Git](https://git-scm.com/book/en/Distributed-Git-Contributing-to-a-Project#Commit-Guidelines)
for best practices around commit messages, and use `git log` to see some examples.
If your pull request addresses a bug or improvement, please create your branch
from Spring Framework's `3.2.x` branch. `master` is reserved for work on new features
for the next major version of the framework. Rest assured that if your pull
request is accepted and merged into `3.2.x`, these changes will also eventually
be merged into `master`.
1. If there is a prior issue, reference the GitHub issue number in the description of the
pull request.
If accepted, your contribution may be heavily modified as needed prior to merging.
You will likely retain author attribution for your Git commits granted that the bulk of
your changes remain intact. You may also be asked to rework the submission.
## Use short branch names
If asked to make corrections, simply push the changes against the same branch, and your
pull request will be updated. In other words, you do not need to create a new pull request
when asked to make changes.
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.
#### Participate in Reviews
Helping to review pull requests is another great way to contribute. Your feedback
can help to shape the implementation of new features. When reviewing pull requests,
however, please refrain from approving or rejecting a PR unless you are a core
committer for the Spring Framework.
## Mind the whitespace
### Build from Source
Please carefully follow the whitespace and formatting conventions already
present in the framework.
See the [Build from Source](https://github.com/spring-projects/spring-framework/wiki/Build-from-Source)
wiki page for instructions on how to check out, build, and import the Spring Framework
source code into your IDE.
1. Tabs, not spaces
1. Unix (LF), not DOS (CRLF) line endings
1. Eliminate all trailing whitespace
1. Wrap Javadoc at 90 characters
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.
1. Latin-1 (ISO-8859-1) encoding for Java sources; use `native2ascii` to convert
if necessary
### Source Code Style
The wiki pages
[Code Style](https://github.com/spring-projects/spring-framework/wiki/Code-Style) and
[IntelliJ IDEA Editor Settings](https://github.com/spring-projects/spring-framework/wiki/IntelliJ-IDEA-Editor-Settings)
define the source file coding standards we use along with some IDEA editor settings we customize.
## Add Apache license header to all new classes
### Reference Docs
```java
/*
* 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.
* 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.
*/
The reference documentation is in the [src/docs/asciidoc](src/docs/asciidoc) directory, in
[Asciidoctor](https://asciidoctor.org/) format. For trivial changes, you may be able to browse,
edit source files, and submit directly from GitHub.
package ...;
```
When making changes locally, execute `./gradlew asciidoctor` and then browse the result under
`build/docs/ref-docs/html5/index.html`.
## Update Apache license header to modified files as necessary
Asciidoctor also supports live editing. For more details see
[AsciiDoc Tooling](https://docs.asciidoctor.org/asciidoctor/latest/tooling/).
Always check the date range in the license header. For example, if you've
modified a file in 2013 whose header still reads
```java
* Copyright 2002-2011 the original author or authors.
```
then be sure to update it to 2013 appropriately
```java
* Copyright 2002-2013 the original author or authors.
```
## Use @since tags for newly-added public API types and methods
e.g.
```java
/**
* ...
*
* @author First Last
* @since 3.2
* @see ...
*/
```
## Submit JUnit test cases for all behavior changes
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.
```java
package org.springframework.beans.factory.support;
/**
* Unit tests for SPR-8954, in which a custom {@link InstantiationAwareBeanPostProcessor}
* forces the predicted type of a FactoryBean, effectively preventing retrieval of the
* bean from calls to #getBeansOfType(FactoryBean.class). The implementation of
* {@link AbstractBeanFactory#isFactoryBean(String, RootBeanDefinition)} now ensures
* that not only the predicted bean type is considered, but also the original bean
* definition's beanClass.
*
* @author Chris Beams
*/
public class Spr8954Tests {
@Test
public void cornerSpr8954() {
// ...
}
}
```
## 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 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:
Author: Nickname <user@mail.com>
Rather, please include your first and last name, properly capitalized, as
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
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
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:
cd spring-framework
git config user.name "First Last"
git config user.email user@mail.com
## Format commit messages
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):
Short (50 chars or less) summary of changes
More detailed explanatory text, if necessary. Wrap it to about 72
characters or so. In some contexts, the first line is treated as the
subject of an email and the rest of the text as the body. The blank
line separating the summary from the body is critical (unless you omit
the body entirely); tools like rebase can get confused if you run the
two together.
Further paragraphs come after blank lines.
- Bullet points are okay, too
- Typically a hyphen or asterisk is used for the bullet, preceded by a
single space, with blank lines in between, but conventions vary here
Issue: SPR-1234, SPR-1235
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. Do not end the subject line with a period
1. Keep 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
1. In the body of the commit message, explain how things worked before this
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:
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
## 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
Subject line:
Follow the same conventions for pull request subject lines as mentioned above
for commit message subject lines.
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
continue one from JIRA
1. Mention the JIRA issue ID
1. Also mention that you have submitted the CLA as described above
Note that for pull requests containing a single commit, GitHub will default the
subject line and body of the pull request to match the subject line and body of
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
Add a comment to the associated JIRA issue(s) linking to your new pull request.
## 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,
and to keep complexity at a minimum. Your changes, if accepted, may be heavily
modified prior to merging. You will retain "Author:" attribution for your Git
commits granted that the bulk of your changes remain intact. You may be asked to
rework the submission for style (as explained above) and/or substance. Again, we
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.
[help documentation]: http://help.github.com/send-pull-requests
[JIRA issue tracker]: https://jira.springsource.org/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
-202
View File
@@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
https://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
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
https://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.
+79 -21
View File
@@ -1,38 +1,96 @@
# <img src="src/docs/spring-framework.png" width="80" height="80"> Spring Framework [![Build Status](https://ci.spring.io/api/v1/teams/spring-framework/pipelines/spring-framework-5.3.x/jobs/build/badge)](https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-5.3.x?groups=Build") [![Revved up by Gradle Enterprise](https://img.shields.io/badge/Revved%20up%20by-Gradle%20Enterprise-06A0CE?logo=Gradle&labelColor=02303A)](https://ge.spring.io/scans?search.rootProjectNames=spring)
## Spring Framework
The Spring Framework provides a comprehensive programming and configuration
model for modern Java-based enterprise applications - on any kind of deployment
platform. A key element of Spring is infrastructural support at the application
level: Spring focuses on the "plumbing" of enterprise applications so that teams
can focus on application-level business logic, without unnecessary ties to
specific deployment environments.
This is the home of the Spring Framework: the foundation for all [Spring projects](https://spring.io/projects). Collectively the Spring Framework and the family of Spring projects are often referred to simply as "Spring".
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.
Spring provides everything required beyond the Java programming language for creating enterprise applications for a wide range of scenarios and architectures. Please read the [Overview](https://docs.spring.io/spring/docs/current/spring-framework-reference/overview.html#spring-introduction) section as reference for a more complete introduction.
[.NET][] and [Python][] variants are available as well.
## Code of Conduct
This project is governed by the [Spring Code of Conduct](CODE_OF_CONDUCT.adoc). By participating, you are expected to uphold this code of conduct. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
## Access to Binaries
For access to artifacts or a distribution zip, see the [Spring Framework Artifacts](https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Artifacts) wiki page.
## 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][].
## Documentation
See the current [Javadoc][] and [reference docs][].
The Spring Framework maintains reference documentation ([published](https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/) and [source](src/docs/asciidoc)), GitHub [wiki pages](https://github.com/spring-projects/spring-framework/wiki), and an
[API reference](https://docs.spring.io/spring-framework/docs/current/javadoc-api/). There are also [guides and tutorials](https://spring.io/guides) across Spring projects.
## 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.
## Micro-Benchmarks
## Issue Tracking
Report issues via the [Spring Framework JIRA]. Understand our issue management
process by reading about [the lifecycle of an issue][]. Think you've found a
bug? Please consider submitting a reproduction project via the
[spring-framework-issues][] GitHub repository. The [readme][] there provides
simple step-by-step instructions.
See the [Micro-Benchmarks](https://github.com/spring-projects/spring-framework/wiki/Micro-Benchmarks) wiki page.
## 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. The only
prerequisites are [Git][] and JDK 1.7+.
## Build from Source
### check out sources
`git clone git://github.com/SpringSource/spring-framework.git`
See the [Build from Source](https://github.com/spring-projects/spring-framework/wiki/Build-from-Source) wiki page and the [CONTRIBUTING.md](CONTRIBUTING.md) file.
### compile and test, build all jars, distribution zips and docs
`./gradlew build`
## Continuous Integration Builds
### install all spring-\* jars into your local Maven cache
`./gradlew install`
Information regarding CI builds can be found in the [Spring Framework Concourse pipeline](ci/README.adoc) documentation.
### import sources into your IDE
Run `./import-into-eclipse.sh` or read `import-into-idea.md` as appropriate.
## Stay in Touch
... and discover more commands with `./gradlew tasks`. See also the [Gradle
build and release FAQ][].
Follow [@SpringCentral](https://twitter.com/springcentral), [@SpringFramework](https://twitter.com/springframework), and its [team members](https://twitter.com/springframework/lists/team/members) on Twitter. In-depth articles can be found at [The Spring Blog](https://spring.io/blog/), and releases are announced via our [news feed](https://spring.io/blog/category/news).
## 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][].
## License
The Spring Framework is released under version 2.0 of the [Apache License][].
The Spring Framework is released under version 2.0 of the [Apache License](https://www.apache.org/licenses/LICENSE-2.0).
[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
[.NET]: https://github.com/SpringSource/spring-net
[Python]: https://github.com/SpringSource/spring-python
[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 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
[Gradle]: http://gradle.org
[`./gradlew`]: http://vimeo.com/34436402
[Git]: http://help.github.com/set-up-git-redirect
[Gradle build and release FAQ]: https://github.com/SpringSource/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
[Apache License]: http://www.apache.org/licenses/LICENSE-2.0
-11
View File
@@ -1,11 +0,0 @@
# Security Policy
## Supported Versions
Please see the
[Spring Framework Versions](https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions)
wiki page.
## Reporting a Vulnerability
Please see https://spring.io/security-policy.
+1030 -403
View File
File diff suppressed because it is too large Load Diff
-35
View File
@@ -1,35 +0,0 @@
# Spring Framework Build
This folder contains the custom plugins and conventions for the Spring Framework build.
They are declared in the `build.gradle` file in this folder.
## Build Conventions
### Compiler conventions
The `org.springframework.build.compile` plugin applies the Java compiler conventions to the build.
## Build Plugins
### Optional dependencies
The `org.springframework.build.optional-dependencies` plugin creates a new `optional`
Gradle configuration - it adds the dependencies to the project's compile and runtime classpath
but doesn't affect the classpath of dependent projects.
This plugin does not provide a `provided` configuration, as the native `compileOnly` and `testCompileOnly`
configurations are preferred.
### API Diff
This plugin uses the [Gradle JApiCmp](https://github.com/melix/japicmp-gradle-plugin) plugin
to generate API Diff reports for each Spring Framework module. This plugin is applied once on the root
project and creates tasks in each framework module. Unlike previous versions of this part of the build,
there is no need for checking out a specific tag. The plugin will fetch the JARs we want to compare the
current working version with. You can generate the reports for all modules or a single module:
```
./gradlew apiDiff -PbaselineVersion=5.1.0.RELEASE
./gradlew :spring-core:apiDiff -PbaselineVersion=5.1.0.RELEASE
```
The reports are located under `build/reports/api-diff/$OLDVERSION_to_$NEWVERSION/`.
-29
View File
@@ -1,29 +0,0 @@
plugins {
id 'java-gradle-plugin'
}
repositories {
mavenCentral()
gradlePluginPortal()
}
dependencies {
implementation "me.champeau.gradle:japicmp-gradle-plugin:0.3.0"
}
gradlePlugin {
plugins {
apiDiffPlugin {
id = "org.springframework.build.api-diff"
implementationClass = "org.springframework.build.api.ApiDiffPlugin"
}
compileConventionsPlugin {
id = "org.springframework.build.compile"
implementationClass = "org.springframework.build.compile.CompilerConventionsPlugin"
}
optionalDependenciesPlugin {
id = "org.springframework.build.optional-dependencies"
implementationClass = "org.springframework.build.optional.OptionalDependenciesPlugin"
}
}
}
-1
View File
@@ -1 +0,0 @@
org.gradle.caching=true
@@ -0,0 +1,158 @@
/*
* 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.
* 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.build.gradle
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskAction
/**
* Gradle plugin that detects identically named, non-empty packages split across multiple
* subprojects, e.g. "org.springframework.context.annotation" existing in both spring-core
* and spring-aspects. Adds a 'detectSplitPackages' task to the current project's task
* collection. If the project already contains a 'check' task (i.e. is a typical Gradle
* project with the "java" plugin applied), the 'check' task will be updated to depend on
* the execution of 'detectSplitPackages'.
*
* By default, all subprojects will be scanned. Use the 'projectsToScan' task property to
* modify this value. Example usage:
*
* apply plugin: 'detect-split-packages // typically applied to root project
*
* detectSplitPackages {
* packagesToScan -= project(":spring-xyz") // scan every project but spring-xyz
* }
*
* @author Rob Winch
* @author Glyn Normington
* @author Chris Beams
*/
public class DetectSplitPackagesPlugin implements Plugin<Project> {
public void apply(Project project) {
def tasks = project.tasks
Task detectSplitPackages = tasks.create("detectSplitPackages", DetectSplitPackagesTask.class)
if (tasks.asMap.containsKey("check")) {
tasks.getByName("check").dependsOn detectSplitPackages
}
}
}
public class DetectSplitPackagesTask extends DefaultTask {
private static final String JAVA_FILE_SUFFIX = ".java"
private static final String PACKAGE_SEPARATOR = "."
private static final String HIDDEN_DIRECTORY_PREFIX = "."
@Input
Set<Project> projectsToScan = project.subprojects
public DetectSplitPackagesTask() {
this.group = "Verification"
this.description = "Detects packages split across two or more subprojects."
}
@TaskAction
public void detectSplitPackages() {
def splitPackages = doDetectSplitPackages()
if (!splitPackages.isEmpty()) {
def message = "The following split package(s) have been detected:\n"
splitPackages.each { pkg, mod ->
message += " - ${pkg} (split across ${mod[0].name} and ${mod[1].name})\n"
}
throw new GradleException(message)
}
}
private Map<String, List<Project>> doDetectSplitPackages() {
def splitPackages = [:]
def mergedProjects = findMergedProjects()
def packagesByProject = mapPackagesByProject()
def projects = packagesByProject.keySet().toArray()
def nProjects = projects.length
for (int i = 0; i < nProjects - 1; i++) {
for (int j = i + 1; j < nProjects - 1; j++) {
def prj_i = projects[i]
def prj_j = projects[j]
def pkgs_i = new HashSet(packagesByProject.get(prj_i))
def pkgs_j = packagesByProject.get(prj_j)
pkgs_i.retainAll(pkgs_j)
if (!pkgs_i.isEmpty()
&& mergedProjects.get(prj_i) != prj_j
&& mergedProjects.get(prj_j) != prj_i) {
pkgs_i.each { pkg ->
def readablePkg = pkg.substring(1).replaceAll(File.separator, PACKAGE_SEPARATOR)
splitPackages[readablePkg] = [prj_i, prj_j]
}
}
}
}
return splitPackages;
}
private Map<Project, Set<String>> mapPackagesByProject() {
def packagesByProject = [:]
this.projectsToScan.each { Project p ->
def packages = new HashSet<String>()
p.sourceSets.main.java.srcDirs.each { File dir ->
findPackages(packages, dir, "")
}
if (!packages.isEmpty()) {
packagesByProject.put(p, packages)
}
}
return packagesByProject;
}
private Map<Project, Project> findMergedProjects() {
def mergedProjects = [:]
this.projectsToScan.findAll { p ->
p.plugins.findPlugin(MergePlugin)
}.findAll { p ->
p.merge.into
}.each { p ->
mergedProjects.put(p, p.merge.into)
}
return mergedProjects
}
private static void findPackages(Set<String> packages, File dir, String packagePath) {
def scanDir = new File(dir, packagePath)
def File[] javaFiles = scanDir.listFiles({ file ->
!file.isDirectory() && file.name.endsWith(JAVA_FILE_SUFFIX)
} as FileFilter)
if (javaFiles != null && javaFiles.length != 0) {
packages.add(packagePath)
}
scanDir.listFiles({ File file ->
file.isDirectory() && !file.name.startsWith(HIDDEN_DIRECTORY_PREFIX)
} as FileFilter).each { File subDir ->
findPackages(packages, dir, packagePath + File.separator + subDir.name)
}
}
}
@@ -0,0 +1,160 @@
/*
* 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.
* 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.build.gradle
import org.gradle.api.*
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
* dependencies (for example Hibernate v3 and v4).
* <p>
* The 'merge' extension should be used to define how projects are merged, for example:
* <pre>
* configure(subprojects) {
* apply plugin: MergePlugin
* }
*
* project("myproject") {
* }
*
* project("myproject-extra") {
* merge.into = project("myproject")
* }
* </pre>
* <p>
* This plugin adds two new configurations:
* <ul>
* <li>merging - Contains the projects being merged into this project<li>
* <li>runtimeMerge - Contains all dependencies that are merge projects. These are used
* to allow an IDE to reference merge projects.</li>
* <ul>
*
* @author Rob Winch
* @author Phillip Webb
*/
class MergePlugin implements Plugin<Project> {
private static boolean attachedProjectsEvaluated;
public void apply(Project project) {
project.plugins.apply(MavenPlugin)
project.plugins.apply(EclipsePlugin)
project.plugins.apply(IdeaPlugin)
MergeModel model = project.extensions.create("merge", MergeModel)
project.configurations.create("merging")
Configuration runtimeMerge = project.configurations.create("runtimeMerge")
// Ensure the IDE can reference merged projects
project.eclipse.classpath.plusConfigurations += [runtimeMerge]
project.idea.module.scopes.PROVIDED.plus += runtimeMerge
// Hook to perform the actual merge logic
project.afterEvaluate{
if(it.merge.into != null) {
setup(it)
}
}
// Hook to build runtimeMerge dependencies
if(!attachedProjectsEvaluated) {
project.gradle.projectsEvaluated{
postProcessProjects(it)
}
attachedProjectsEvaluated = true;
}
}
private void setup(Project project) {
project.merge.into.dependencies.add("merging", project)
project.dependencies.add("provided", project.merge.into.sourceSets.main.output)
project.dependencies.add("runtimeMerge", project.merge.into)
setupTaskDependencies(project)
setupMaven(project)
}
private void setupTaskDependencies(Project 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) {
task.enabled = false
task.dependsOn(project.merge.into.tasks.findByPath(it))
}
}
// update 'into' project artifacts to contain the source artifact contents
project.merge.into.sourcesJar.from(project.sourcesJar.source)
project.merge.into.jar.from(project.sourceSets.main.output)
project.merge.into.javadoc {
source += project.javadoc.source
classpath += project.javadoc.classpath
}
}
private void setupMaven(Project project) {
project.configurations.each { configuration ->
Conf2ScopeMapping mapping = project.conf2ScopeMappings.getMapping([configuration])
if(mapping.scope) {
Configuration intoConfiguration = project.merge.into.configurations.create(
project.name + "-" + configuration.name)
configuration.excludeRules.each {
configuration.exclude([
(ExcludeRule.GROUP_KEY) : it.group,
(ExcludeRule.MODULE_KEY) : it.module])
}
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)) {
intoConfiguration.dependencies.add(it)
}
}
project.merge.into.install.repositories.mavenInstaller.pom.scopeMappings.addMapping(
mapping.priority + 100, intoConfiguration, mapping.scope)
}
}
}
private postProcessProjects(Gradle gradle) {
gradle.allprojects(new Action<Project>() {
public void execute(Project project) {
project.configurations.getByName("runtime").allDependencies.withType(ProjectDependency).each{
Configuration dependsOnMergedFrom = it.dependencyProject.configurations.getByName("merging");
dependsOnMergedFrom.dependencies.each{ dep ->
project.dependencies.add("runtimeMerge", dep.dependencyProject)
}
}
}
});
}
}
class MergeModel {
Project into;
}
@@ -0,0 +1,57 @@
/*
* 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.
* 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.build.gradle
import org.gradle.api.Plugin
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.
*
* @author Phillip Webb
*/
class TestSourceSetDependenciesPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.afterEvaluate {
Set<ProjectDependency> projectDependencies = new LinkedHashSet<ProjectDependency>()
collectProjectDependencies(projectDependencies, project)
projectDependencies.each {
project.dependencies.add("testCompile", it.dependencyProject.sourceSets.test.output)
}
}
}
private void collectProjectDependencies(Set<ProjectDependency> projectDependencies,
Project project) {
for(def configurationName in ["compile", "optional", "provided", "testCompile"]) {
Configuration configuration = project.getConfigurations().findByName(configurationName)
if(configuration) {
configuration.dependencies.findAll { it instanceof ProjectDependency }.each {
projectDependencies.add(it)
collectProjectDependencies(projectDependencies, it.dependencyProject)
}
}
}
}
}
@@ -1,115 +0,0 @@
/*
* Copyright 2002-2019 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
*
* https://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.build.api;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import me.champeau.gradle.japicmp.JapicmpPlugin;
import me.champeau.gradle.japicmp.JapicmpTask;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.plugins.JavaBasePlugin;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin;
import org.gradle.api.tasks.TaskProvider;
import org.gradle.jvm.tasks.Jar;
/**
* {@link Plugin} that applies the {@code "japicmp-gradle-plugin"}
* and create tasks for all subprojects, diffing the public API one by one
* and creating the reports in {@code "build/reports/api-diff/$OLDVERSION_to_$NEWVERSION/"}.
* <p>{@code "./gradlew apiDiff -PbaselineVersion=5.1.0.RELEASE"} will output the
* reports for the API diff between the baseline version and the current one for all modules.
* You can limit the report to a single module with
* {@code "./gradlew :spring-core:apiDiff -PbaselineVersion=5.1.0.RELEASE"}.
*
* @author Brian Clozel
*/
public class ApiDiffPlugin implements Plugin<Project> {
public static final String TASK_NAME = "apiDiff";
private static final String BASELINE_VERSION_PROPERTY = "baselineVersion";
private static final List<String> PACKAGE_INCLUDES = Collections.singletonList("org.springframework.*");
@Override
public void apply(Project project) {
if (project.hasProperty(BASELINE_VERSION_PROPERTY) && project.equals(project.getRootProject())) {
project.getPluginManager().apply(JapicmpPlugin.class);
project.getPlugins().withType(JapicmpPlugin.class,
plugin -> applyApiDiffConventions(project));
}
}
private void applyApiDiffConventions(Project project) {
String baselineVersion = project.property(BASELINE_VERSION_PROPERTY).toString();
project.subprojects(subProject -> createApiDiffTask(baselineVersion, subProject));
}
private void createApiDiffTask(String baselineVersion, Project project) {
if (isProjectEligible(project)) {
JapicmpTask apiDiff = project.getTasks().create(TASK_NAME, JapicmpTask.class);
apiDiff.setDescription("Generates an API diff report with japicmp");
apiDiff.setGroup(JavaBasePlugin.DOCUMENTATION_GROUP);
apiDiff.setOldClasspath(project.files(createBaselineConfiguration(baselineVersion, project)));
TaskProvider<Jar> jar = project.getTasks().withType(Jar.class).named("jar");
apiDiff.setNewArchives(project.getLayout().files(jar.get().getArchiveFile().get().getAsFile()));
apiDiff.setNewClasspath(getRuntimeClassPath(project));
apiDiff.setPackageIncludes(PACKAGE_INCLUDES);
apiDiff.setOnlyModified(true);
apiDiff.setIgnoreMissingClasses(true);
// Ignore Kotlin metadata annotations since they contain
// illegal HTML characters and fail the report generation
apiDiff.setAnnotationExcludes(Collections.singletonList("@kotlin.Metadata"));
apiDiff.setHtmlOutputFile(getOutputFile(baselineVersion, project));
apiDiff.dependsOn(project.getTasks().getByName("jar"));
}
}
private boolean isProjectEligible(Project project) {
return project.getPlugins().hasPlugin(JavaPlugin.class)
&& project.getPlugins().hasPlugin(MavenPublishPlugin.class);
}
private Configuration createBaselineConfiguration(String baselineVersion, Project project) {
String baseline = String.join(":",
project.getGroup().toString(), project.getName(), baselineVersion);
Dependency baselineDependency = project.getDependencies().create(baseline + "@jar");
return project.getRootProject().getConfigurations().detachedConfiguration(baselineDependency);
}
private Configuration getRuntimeClassPath(Project project) {
return project.getConfigurations().getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME);
}
private File getOutputFile(String baseLineVersion, Project project) {
Path outDir = Paths.get(project.getRootProject().getBuildDir().getAbsolutePath(),
"reports", "api-diff",
baseLineVersion + "_to_" + project.getRootProject().getVersion());
return project.file(outDir.resolve(project.getName() + ".html").toString());
}
}
@@ -1,89 +0,0 @@
/*
* Copyright 2002-2021 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
*
* https://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.build.compile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.plugins.JavaLibraryPlugin;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.compile.JavaCompile;
/**
* {@link Plugin} that applies conventions for compiling Java sources in Spring Framework.
*
* @author Brian Clozel
* @author Sam Brannen
* @author Sebastien Deleuze
*/
public class CompilerConventionsPlugin implements Plugin<Project> {
private static final List<String> COMPILER_ARGS;
private static final List<String> TEST_COMPILER_ARGS;
static {
List<String> commonCompilerArgs = Arrays.asList(
"-Xlint:serial", "-Xlint:cast", "-Xlint:classfile", "-Xlint:dep-ann",
"-Xlint:divzero", "-Xlint:empty", "-Xlint:finally", "-Xlint:overrides",
"-Xlint:path", "-Xlint:processing", "-Xlint:static", "-Xlint:try", "-Xlint:-options",
"-parameters"
);
COMPILER_ARGS = new ArrayList<>();
COMPILER_ARGS.addAll(commonCompilerArgs);
COMPILER_ARGS.addAll(Arrays.asList(
"-Xlint:varargs", "-Xlint:fallthrough", "-Xlint:rawtypes", "-Xlint:deprecation",
"-Xlint:unchecked", "-Werror"
));
TEST_COMPILER_ARGS = new ArrayList<>();
TEST_COMPILER_ARGS.addAll(commonCompilerArgs);
TEST_COMPILER_ARGS.addAll(Arrays.asList("-Xlint:-varargs", "-Xlint:-fallthrough", "-Xlint:-rawtypes",
"-Xlint:-deprecation", "-Xlint:-unchecked"));
}
@Override
public void apply(Project project) {
project.getPlugins().withType(JavaLibraryPlugin.class, javaPlugin -> applyJavaCompileConventions(project));
}
/**
* Applies the common Java compiler options for main sources, test fixture sources, and
* test sources.
* @param project the current project
*/
private void applyJavaCompileConventions(Project project) {
JavaPluginConvention java = project.getConvention().getPlugin(JavaPluginConvention.class);
project.getTasks().withType(JavaCompile.class)
.matching(compileTask -> compileTask.getName().equals(JavaPlugin.COMPILE_JAVA_TASK_NAME))
.forEach(compileTask -> {
compileTask.getOptions().setCompilerArgs(COMPILER_ARGS);
compileTask.getOptions().setEncoding("UTF-8");
});
project.getTasks().withType(JavaCompile.class)
.matching(compileTask -> compileTask.getName().equals(JavaPlugin.COMPILE_TEST_JAVA_TASK_NAME)
|| compileTask.getName().equals("compileTestFixturesJava"))
.forEach(compileTask -> {
compileTask.getOptions().setCompilerArgs(TEST_COMPILER_ARGS);
compileTask.getOptions().setEncoding("UTF-8");
});
}
}
@@ -1,59 +0,0 @@
/*
* Copyright 2002-2021 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
*
* https://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.build.optional;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.attributes.Usage;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.plugins.ide.eclipse.EclipsePlugin;
import org.gradle.plugins.ide.eclipse.model.EclipseModel;
/**
* A {@code Plugin} that adds support for Maven-style optional dependencies. Creates a new
* {@code optional} configuration. The {@code optional} configuration is part of the
* project's compile and runtime classpaths but does not affect the classpath of
* dependent projects.
*
* @author Andy Wilkinson
*/
public class OptionalDependenciesPlugin implements Plugin<Project> {
/**
* Name of the {@code optional} configuration.
*/
public static final String OPTIONAL_CONFIGURATION_NAME = "optional";
@Override
public void apply(Project project) {
Configuration optional = project.getConfigurations().create("optional");
optional.setCanBeConsumed(false);
optional.setCanBeResolved(false);
project.getPlugins().withType(JavaPlugin.class, (javaPlugin) -> {
SourceSetContainer sourceSets = project.getConvention().getPlugin(JavaPluginConvention.class)
.getSourceSets();
sourceSets.all((sourceSet) -> {
project.getConfigurations().getByName(sourceSet.getCompileClasspathConfigurationName()).extendsFrom(optional);
project.getConfigurations().getByName(sourceSet.getRuntimeClasspathConfigurationName()).extendsFrom(optional);
});
});
}
}
@@ -0,0 +1 @@
implementation-class=org.springframework.build.gradle.DetectSplitPackagesPlugin
@@ -0,0 +1 @@
implementation-class=org.springframework.build.gradle.MergePlugin
@@ -0,0 +1 @@
implementation-class=org.springframework.build.gradle.TestSourceSetDependenciesPlugin
-57
View File
@@ -1,57 +0,0 @@
== Spring Framework Concourse pipeline
The Spring Framework uses https://concourse-ci.org/[Concourse] for its CI build and other automated tasks.
The Spring team has a dedicated Concourse instance available at https://ci.spring.io with a build pipeline
for https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-5.3.x[Spring Framework 5.3.x].
=== Setting up your development environment
If you're part of the Spring Framework project on GitHub, you can get access to CI management features.
First, you need to go to https://ci.spring.io and install the client CLI for your platform (see bottom right of the screen).
You can then login with the instance using:
[source]
----
$ fly -t spring login -n spring-framework -c https://ci.spring.io
----
Once logged in, you should get something like:
[source]
----
$ fly ts
name url team expiry
spring https://ci.spring.io spring-framework Wed, 25 Mar 2020 17:45:26 UTC
----
=== Pipeline configuration and structure
The build pipelines are described in `pipeline.yml` file.
This file is listing Concourse resources, i.e. build inputs and outputs such as container images, artifact repositories, source repositories, notification services, etc.
It also describes jobs (a job is a sequence of inputs, tasks and outputs); jobs are organized by groups.
The `pipeline.yml` definition contains `((parameters))` which are loaded from the `parameters.yml` file or from our https://docs.cloudfoundry.org/credhub/[credhub instance].
You'll find in this folder the following resources:
* `pipeline.yml` the build pipeline
* `parameters.yml` the build parameters used for the pipeline
* `images/` holds the container images definitions used in this pipeline
* `scripts/` holds the build scripts that ship within the CI container images
* `tasks` contains the task definitions used in the main `pipeline.yml`
=== Updating the build pipeline
Updating files on the repository is not enough to update the build pipeline, as changes need to be applied.
The pipeline can be deployed using the following command:
[source]
----
$ fly -t spring set-pipeline -p spring-framework-5.3.x -c ci/pipeline.yml -l ci/parameters.yml
----
NOTE: This assumes that you have credhub integration configured with the appropriate secrets.
-20
View File
@@ -1,20 +0,0 @@
changelog:
repository: spring-projects/spring-framework
sections:
- title: ":star: New Features"
labels:
- "type: enhancement"
- title: ":lady_beetle: Bug Fixes"
labels:
- "type: bug"
- "type: regression"
- title: ":notebook_with_decorative_cover: Documentation"
labels:
- "type: documentation"
- title: ":hammer: Dependency Upgrades"
sort: "title"
labels:
- "type: dependency-upgrade"
contributors:
exclude:
names: ["bclozel", "jhoeller", "poutsma", "rstoyanchev", "sbrannen", "sdeleuze", "snicoll"]
-10
View File
@@ -1,10 +0,0 @@
logging:
level:
io.spring.concourse: DEBUG
spring:
main:
banner-mode: off
sonatype:
exclude:
- 'build-info\.json'
- '.*\.zip'
-21
View File
@@ -1,21 +0,0 @@
== CI Images
These images are used by CI to run the actual builds.
To build the image locally run the following from this directory:
----
$ docker build --no-cache -f <image-folder>/Dockerfile .
----
For example
----
$ docker build --no-cache -f spring-framework-ci-image/Dockerfile .
----
To test run:
----
$ docker run -it --entrypoint /bin/bash <SHA>
----
-10
View File
@@ -1,10 +0,0 @@
FROM ubuntu:jammy-20240111
ADD setup.sh /setup.sh
ADD get-jdk-url.sh /get-jdk-url.sh
RUN ./setup.sh java8
ENV JAVA_HOME /opt/openjdk/java8
ENV JDK17 /opt/openjdk/java17
ENV PATH $JAVA_HOME/bin:$PATH
-14
View File
@@ -1,14 +0,0 @@
#!/bin/bash
set -e
case "$1" in
java8)
echo "https://github.com/bell-sw/Liberica/releases/download/8u402%2B7/bellsoft-jdk8u402+7-linux-amd64.tar.gz"
;;
java17)
echo "https://github.com/bell-sw/Liberica/releases/download/17.0.10%2B13/bellsoft-jdk17.0.10+13-linux-amd64.tar.gz"
;;
*)
echo $"Unknown java version"
exit 1
esac
-40
View File
@@ -1,40 +0,0 @@
#!/bin/bash
set -ex
###########################################################
# UTILS
###########################################################
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install --no-install-recommends -y tzdata ca-certificates net-tools libxml2-utils git curl libudev1 libxml2-utils iptables iproute2 jq fontconfig
ln -fs /usr/share/zoneinfo/UTC /etc/localtime
dpkg-reconfigure --frontend noninteractive tzdata
rm -rf /var/lib/apt/lists/*
curl https://raw.githubusercontent.com/spring-io/concourse-java-scripts/v0.0.4/concourse-java.sh > /opt/concourse-java.sh
###########################################################
# JAVA
###########################################################
mkdir -p /opt/openjdk
pushd /opt/openjdk > /dev/null
for jdk in java8 java17
do
JDK_URL=$( /get-jdk-url.sh $jdk )
mkdir $jdk
pushd $jdk > /dev/null
curl -L ${JDK_URL} | tar zx --strip-components=1
test -f bin/java
test -f bin/javac
popd > /dev/null
done
popd
###########################################################
# GRADLE ENTERPRISE
###########################################################
cd /
mkdir ~/.gradle
echo 'systemProp.user.name=concourse' > ~/.gradle/gradle.properties
-11
View File
@@ -1,11 +0,0 @@
github-repo: "https://github.com/spring-projects/spring-framework.git"
github-repo-name: "spring-projects/spring-framework"
sonatype-staging-profile: "org.springframework"
docker-hub-organization: "springci"
artifactory-server: "https://repo.spring.io"
branch: "5.3.x"
milestone: "5.3.x"
build-name: "spring-framework"
pipeline-name: "spring-framework"
concourse-url: "https://ci.spring.io"
task-timeout: 1h00m
-399
View File
@@ -1,399 +0,0 @@
anchors:
git-repo-resource-source: &git-repo-resource-source
uri: ((github-repo))
username: ((github-username))
password: ((github-ci-release-token))
branch: ((branch))
gradle-enterprise-task-params: &gradle-enterprise-task-params
GRADLE_ENTERPRISE_ACCESS_KEY: ((gradle_enterprise_secret_access_key))
GRADLE_ENTERPRISE_CACHE_USERNAME: ((gradle_enterprise_cache_user.username))
GRADLE_ENTERPRISE_CACHE_PASSWORD: ((gradle_enterprise_cache_user.password))
sonatype-task-params: &sonatype-task-params
SONATYPE_USERNAME: ((sonatype-username))
SONATYPE_PASSWORD: ((sonatype-password))
SONATYPE_URL: ((sonatype-url))
SONATYPE_STAGING_PROFILE: ((sonatype-staging-profile))
artifactory-task-params: &artifactory-task-params
ARTIFACTORY_SERVER: ((artifactory-server))
ARTIFACTORY_USERNAME: ((artifactory-username))
ARTIFACTORY_PASSWORD: ((artifactory-password))
build-project-task-params: &build-project-task-params
BRANCH: ((branch))
<<: *gradle-enterprise-task-params
docker-resource-source: &docker-resource-source
username: ((docker-hub-username))
password: ((docker-hub-password))
slack-fail-params: &slack-fail-params
text: >
:concourse-failed: <https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}|${BUILD_PIPELINE_NAME} ${BUILD_JOB_NAME} failed!>
[$TEXT_FILE_CONTENT]
text_file: git-repo/build/build-scan-uri.txt
silent: true
icon_emoji: ":concourse:"
username: concourse-ci
changelog-task-params: &changelog-task-params
name: generated-changelog/tag
tag: generated-changelog/tag
body: generated-changelog/changelog.md
github-task-params: &github-task-params
GITHUB_USERNAME: ((github-username))
GITHUB_TOKEN: ((github-ci-release-token))
resource_types:
- name: registry-image
type: registry-image
source:
<<: *docker-resource-source
repository: concourse/registry-image-resource
tag: 1.7.1
- name: artifactory-resource
type: registry-image
source:
<<: *docker-resource-source
repository: springio/artifactory-resource
tag: 0.0.18
- name: github-release
type: registry-image
source:
<<: *docker-resource-source
repository: concourse/github-release-resource
tag: 1.8.0
- name: github-status-resource
type: registry-image
source:
<<: *docker-resource-source
repository: dpb587/github-status-resource
tag: master
- name: slack-notification
type: registry-image
source:
<<: *docker-resource-source
repository: cfcommunity/slack-notification-resource
tag: latest
resources:
- name: git-repo
type: git
icon: github
source:
<<: *git-repo-resource-source
- name: every-morning
type: time
icon: alarm
source:
start: 8:00 AM
stop: 9:00 AM
location: Europe/Vienna
- name: ci-images-git-repo
type: git
icon: github
source:
uri: ((github-repo))
branch: ((branch))
paths: ["ci/images/*"]
- name: ci-image
type: registry-image
icon: docker
source:
<<: *docker-resource-source
repository: ((docker-hub-organization))/spring-framework-ci
tag: ((milestone))
- name: artifactory-repo
type: artifactory-resource
icon: package-variant
source:
uri: ((artifactory-server))
username: ((artifactory-username))
password: ((artifactory-password))
build_name: ((build-name))
- name: repo-status-build
type: github-status-resource
icon: eye-check-outline
source:
repository: ((github-repo-name))
access_token: ((github-ci-status-token))
branch: ((branch))
context: build
- name: repo-status-jdk17-build
type: github-status-resource
icon: eye-check-outline
source:
repository: ((github-repo-name))
access_token: ((github-ci-status-token))
branch: ((branch))
context: jdk17-build
- name: slack-alert
type: slack-notification
icon: slack
source:
url: ((slack-webhook-url))
- name: github-pre-release
type: github-release
icon: briefcase-download-outline
source:
owner: spring-projects
repository: spring-framework
access_token: ((github-ci-release-token))
pre_release: true
release: false
- name: github-release
type: github-release
icon: briefcase-download
source:
owner: spring-projects
repository: spring-framework
access_token: ((github-ci-release-token))
pre_release: false
jobs:
- name: build-ci-images
plan:
- get: git-repo
- get: ci-images-git-repo
trigger: true
- task: build-ci-image
privileged: true
file: git-repo/ci/tasks/build-ci-image.yml
output_mapping:
image: ci-image
vars:
ci-image-name: ci-image
<<: *docker-resource-source
- put: ci-image
params:
image: ci-image/image.tar
- name: build
serial: true
public: true
plan:
- get: ci-image
- get: git-repo
trigger: true
- put: repo-status-build
params: { state: "pending", commit: "git-repo" }
- do:
- task: build-project
image: ci-image
file: git-repo/ci/tasks/build-project.yml
privileged: true
timeout: ((task-timeout))
params:
<<: *build-project-task-params
on_failure:
do:
- put: repo-status-build
params: { state: "failure", commit: "git-repo" }
- put: slack-alert
params:
<<: *slack-fail-params
- put: repo-status-build
params: { state: "success", commit: "git-repo" }
- put: artifactory-repo
params: &artifactory-params
signing_key: ((signing-key))
signing_passphrase: ((signing-passphrase))
repo: libs-snapshot-local
folder: distribution-repository
build_uri: "https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}"
build_number: "${BUILD_PIPELINE_NAME}-${BUILD_JOB_NAME}-${BUILD_NAME}"
disable_checksum_uploads: true
threads: 8
artifact_set:
- include:
- "/**/spring-*.zip"
properties:
"zip.name": "spring-framework"
"zip.displayname": "Spring Framework"
"zip.deployed": "false"
- include:
- "/**/spring-*-docs.zip"
properties:
"zip.type": "docs"
- include:
- "/**/spring-*-dist.zip"
properties:
"zip.type": "dist"
- include:
- "/**/spring-*-schema.zip"
properties:
"zip.type": "schema"
get_params:
threads: 8
- name: jdk17-build
serial: true
public: true
plan:
- get: ci-image
- get: git-repo
- get: every-morning
trigger: true
- put: repo-status-jdk17-build
params: { state: "pending", commit: "git-repo" }
- do:
- task: check-project
image: ci-image
file: git-repo/ci/tasks/check-project.yml
privileged: true
timeout: ((task-timeout))
params:
TEST_TOOLCHAIN: 17
<<: *build-project-task-params
on_failure:
do:
- put: repo-status-jdk17-build
params: { state: "failure", commit: "git-repo" }
- put: slack-alert
params:
<<: *slack-fail-params
- put: repo-status-jdk17-build
params: { state: "success", commit: "git-repo" }
- name: stage-milestone
serial: true
plan:
- get: ci-image
- get: git-repo
trigger: false
- task: stage
image: ci-image
file: git-repo/ci/tasks/stage-version.yml
params:
RELEASE_TYPE: M
<<: *gradle-enterprise-task-params
- put: artifactory-repo
params:
<<: *artifactory-params
repo: libs-staging-local
- put: git-repo
params:
repository: stage-git-repo
- name: promote-milestone
serial: true
plan:
- get: ci-image
- get: git-repo
trigger: false
- get: artifactory-repo
trigger: false
passed: [stage-milestone]
params:
download_artifacts: false
save_build_info: true
- task: promote
file: git-repo/ci/tasks/promote-version.yml
params:
RELEASE_TYPE: M
<<: *artifactory-task-params
- task: generate-changelog
file: git-repo/ci/tasks/generate-changelog.yml
params:
RELEASE_TYPE: M
<<: *github-task-params
- put: github-pre-release
params:
<<: *changelog-task-params
- name: stage-rc
serial: true
plan:
- get: ci-image
- get: git-repo
trigger: false
- task: stage
image: ci-image
file: git-repo/ci/tasks/stage-version.yml
params:
RELEASE_TYPE: RC
<<: *gradle-enterprise-task-params
- put: artifactory-repo
params:
<<: *artifactory-params
repo: libs-staging-local
- put: git-repo
params:
repository: stage-git-repo
- name: promote-rc
serial: true
plan:
- get: ci-image
- get: git-repo
trigger: false
- get: artifactory-repo
trigger: false
passed: [stage-rc]
params:
download_artifacts: false
save_build_info: true
- task: promote
file: git-repo/ci/tasks/promote-version.yml
params:
RELEASE_TYPE: RC
<<: *artifactory-task-params
- task: generate-changelog
file: git-repo/ci/tasks/generate-changelog.yml
params:
RELEASE_TYPE: RC
<<: *github-task-params
- put: github-pre-release
params:
<<: *changelog-task-params
- name: stage-release
serial: true
plan:
- get: ci-image
- get: git-repo
trigger: false
- task: stage
image: ci-image
file: git-repo/ci/tasks/stage-version.yml
params:
RELEASE_TYPE: RELEASE
<<: *gradle-enterprise-task-params
- put: artifactory-repo
params:
<<: *artifactory-params
repo: libs-staging-local
- put: git-repo
params:
repository: stage-git-repo
- name: promote-release
serial: true
plan:
- get: ci-image
- get: git-repo
trigger: false
- get: artifactory-repo
trigger: false
passed: [stage-release]
params:
download_artifacts: true
save_build_info: true
- task: promote
file: git-repo/ci/tasks/promote-version.yml
params:
RELEASE_TYPE: RELEASE
<<: *artifactory-task-params
<<: *sonatype-task-params
- name: create-github-release
serial: true
plan:
- get: ci-image
- get: git-repo
- get: artifactory-repo
trigger: true
passed: [promote-release]
params:
download_artifacts: false
save_build_info: true
- task: generate-changelog
file: git-repo/ci/tasks/generate-changelog.yml
params:
RELEASE_TYPE: RELEASE
<<: *github-task-params
- put: github-release
params:
<<: *changelog-task-params
groups:
- name: "builds"
jobs: ["build", "jdk17-build"]
- name: "releases"
jobs: ["stage-milestone", "stage-rc", "stage-release", "promote-milestone", "promote-rc", "promote-release", "create-github-release"]
- name: "ci-images"
jobs: ["build-ci-images"]
-8
View File
@@ -1,8 +0,0 @@
#!/bin/bash
set -e
source $(dirname $0)/common.sh
pushd git-repo > /dev/null
./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false --no-daemon --max-workers=4 check
popd > /dev/null
-9
View File
@@ -1,9 +0,0 @@
#!/bin/bash
set -e
source $(dirname $0)/common.sh
repository=$(pwd)/distribution-repository
pushd git-repo > /dev/null
./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false --no-daemon --max-workers=4 -PdeploymentRepository=${repository} build publishAllPublicationsToDeploymentRepository
popd > /dev/null
-9
View File
@@ -1,9 +0,0 @@
#!/bin/bash
set -e
source $(dirname $0)/common.sh
pushd git-repo > /dev/null
./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false -Porg.gradle.java.installations.fromEnv=JDK17 \
-PmainToolchain=${MAIN_TOOLCHAIN} -PtestToolchain=${TEST_TOOLCHAIN} --no-daemon --max-workers=4 check
popd > /dev/null
-2
View File
@@ -1,2 +0,0 @@
source /opt/concourse-java.sh
setup_symlinks
-12
View File
@@ -1,12 +0,0 @@
#!/bin/bash
set -e
CONFIG_DIR=git-repo/ci/config
version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
java -jar /github-changelog-generator.jar \
--spring.config.location=${CONFIG_DIR}/changelog-generator.yml \
${version} generated-changelog/changelog.md
echo ${version} > generated-changelog/version
echo v${version} > generated-changelog/tag
-18
View File
@@ -1,18 +0,0 @@
#!/bin/bash
source $(dirname $0)/common.sh
CONFIG_DIR=git-repo/ci/config
version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
export BUILD_INFO_LOCATION=$(pwd)/artifactory-repo/build-info.json
java -jar /concourse-release-scripts.jar \
--spring.config.location=${CONFIG_DIR}/release-scripts.yml \
publishToCentral $RELEASE_TYPE $BUILD_INFO_LOCATION artifactory-repo || { exit 1; }
java -jar /concourse-release-scripts.jar \
--spring.config.location=${CONFIG_DIR}/release-scripts.yml \
promote $RELEASE_TYPE $BUILD_INFO_LOCATION || { exit 1; }
echo "Promotion complete"
echo $version > version/version
-50
View File
@@ -1,50 +0,0 @@
#!/bin/bash
set -e
source $(dirname $0)/common.sh
repository=$(pwd)/distribution-repository
pushd git-repo > /dev/null
git fetch --tags --all > /dev/null
popd > /dev/null
git clone git-repo stage-git-repo > /dev/null
pushd stage-git-repo > /dev/null
snapshotVersion=$( awk -F '=' '$1 == "version" { print $2 }' gradle.properties )
if [[ $RELEASE_TYPE = "M" ]]; then
stageVersion=$( get_next_milestone_release $snapshotVersion)
nextVersion=$snapshotVersion
elif [[ $RELEASE_TYPE = "RC" ]]; then
stageVersion=$( get_next_rc_release $snapshotVersion)
nextVersion=$snapshotVersion
elif [[ $RELEASE_TYPE = "RELEASE" ]]; then
stageVersion=$( get_next_release $snapshotVersion)
nextVersion=$( bump_version_number $snapshotVersion)
else
echo "Unknown release type $RELEASE_TYPE" >&2; exit 1;
fi
echo "Staging $stageVersion (next version will be $nextVersion)"
sed -i "s/version=$snapshotVersion/version=$stageVersion/" gradle.properties
git config user.name "Spring Builds" > /dev/null
git config user.email "spring-builds@users.noreply.github.com" > /dev/null
git add gradle.properties > /dev/null
git commit -m"Release v$stageVersion" > /dev/null
git tag -a "v$stageVersion" -m"Release v$stageVersion" > /dev/null
./gradlew --no-daemon --max-workers=4 -PdeploymentRepository=${repository} build publishAllPublicationsToDeploymentRepository
git reset --hard HEAD^ > /dev/null
if [[ $nextVersion != $snapshotVersion ]]; then
echo "Setting next development version (v$nextVersion)"
sed -i "s/version=$snapshotVersion/version=$nextVersion/" gradle.properties
git add gradle.properties > /dev/null
git commit -m"Next development version (v$nextVersion)" > /dev/null
fi;
echo "Staging Complete"
popd > /dev/null
-29
View File
@@ -1,29 +0,0 @@
---
platform: linux
image_resource:
type: registry-image
source:
repository: concourse/oci-build-task
tag: 0.10.0
username: ((docker-hub-username))
password: ((docker-hub-password))
inputs:
- name: ci-images-git-repo
outputs:
- name: image
caches:
- path: ci-image-cache
params:
CONTEXT: ci-images-git-repo/ci/images
DOCKERFILE: ci-images-git-repo/ci/images/ci-image/Dockerfile
DOCKER_HUB_AUTH: ((docker-hub-auth))
run:
path: /bin/sh
args:
- "-c"
- |
mkdir -p /root/.docker
cat > /root/.docker/config.json <<EOF
{ "auths": { "https://index.docker.io/v1/": { "auth": "$DOCKER_HUB_AUTH" }}}
EOF
build
-19
View File
@@ -1,19 +0,0 @@
---
platform: linux
inputs:
- name: git-repo
caches:
- path: gradle
params:
BRANCH:
CI: true
GRADLE_ENTERPRISE_ACCESS_KEY:
GRADLE_ENTERPRISE_CACHE_USERNAME:
GRADLE_ENTERPRISE_CACHE_PASSWORD:
GRADLE_ENTERPRISE_URL: https://ge.spring.io
run:
path: bash
args:
- -ec
- |
${PWD}/git-repo/ci/scripts/build-pr.sh
-22
View File
@@ -1,22 +0,0 @@
---
platform: linux
inputs:
- name: git-repo
outputs:
- name: distribution-repository
- name: git-repo
caches:
- path: gradle
params:
BRANCH:
CI: true
GRADLE_ENTERPRISE_ACCESS_KEY:
GRADLE_ENTERPRISE_CACHE_USERNAME:
GRADLE_ENTERPRISE_CACHE_PASSWORD:
GRADLE_ENTERPRISE_URL: https://ge.spring.io
run:
path: bash
args:
- -ec
- |
${PWD}/git-repo/ci/scripts/build-project.sh
-24
View File
@@ -1,24 +0,0 @@
---
platform: linux
inputs:
- name: git-repo
outputs:
- name: distribution-repository
- name: git-repo
caches:
- path: gradle
params:
BRANCH:
CI: true
MAIN_TOOLCHAIN:
TEST_TOOLCHAIN:
GRADLE_ENTERPRISE_ACCESS_KEY:
GRADLE_ENTERPRISE_CACHE_USERNAME:
GRADLE_ENTERPRISE_CACHE_PASSWORD:
GRADLE_ENTERPRISE_URL: https://ge.spring.io
run:
path: bash
args:
- -ec
- |
${PWD}/git-repo/ci/scripts/check-project.sh
-22
View File
@@ -1,22 +0,0 @@
---
platform: linux
image_resource:
type: registry-image
source:
repository: springio/github-changelog-generator
tag: '0.0.7'
username: ((docker-hub-username))
password: ((docker-hub-password))
inputs:
- name: git-repo
- name: artifactory-repo
outputs:
- name: generated-changelog
params:
GITHUB_ORGANIZATION:
GITHUB_REPO:
GITHUB_USERNAME:
GITHUB_TOKEN:
RELEASE_TYPE:
run:
path: git-repo/ci/scripts/generate-changelog.sh
-25
View File
@@ -1,25 +0,0 @@
---
platform: linux
image_resource:
type: registry-image
source:
repository: springio/concourse-release-scripts
tag: '0.3.4'
username: ((docker-hub-username))
password: ((docker-hub-password))
inputs:
- name: git-repo
- name: artifactory-repo
outputs:
- name: version
params:
RELEASE_TYPE:
ARTIFACTORY_SERVER:
ARTIFACTORY_USERNAME:
ARTIFACTORY_PASSWORD:
SONATYPE_USER:
SONATYPE_PASSWORD:
SONATYPE_URL:
SONATYPE_STAGING_PROFILE:
run:
path: git-repo/ci/scripts/promote-version.sh
-17
View File
@@ -1,17 +0,0 @@
---
platform: linux
inputs:
- name: git-repo
outputs:
- name: stage-git-repo
- name: distribution-repository
params:
RELEASE_TYPE:
CI: true
GRADLE_ENTERPRISE_CACHE_USERNAME:
GRADLE_ENTERPRISE_CACHE_PASSWORD:
GRADLE_ENTERPRISE_URL: https://ge.spring.io
caches:
- path: gradle
run:
path: git-repo/ci/scripts/stage-version.sh
-23
View File
@@ -1,23 +0,0 @@
description = "Spring Framework (Bill of Materials)"
apply plugin: 'java-platform'
apply from: "$rootDir/gradle/publications.gradle"
group = "org.springframework"
dependencies {
constraints {
parent.moduleProjects.sort { "$it.name" }.each {
api it
}
}
}
publishing {
publications {
mavenJava(MavenPublication) {
artifactId = 'spring-framework-bom'
from components.javaPlatform
}
}
}
+1 -5
View File
@@ -1,5 +1 @@
version=5.3.32
org.gradle.jvmargs=-Xmx2048m
org.gradle.caching=true
org.gradle.parallel=true
kotlin.stdlib.default.dependency=false
version=3.2.7.RELEASE
-30
View File
@@ -1,30 +0,0 @@
tasks.findByName("dokkaHtmlPartial")?.configure {
outputDirectory.set(new File(buildDir, "docs/kdoc"))
dokkaSourceSets {
configureEach {
sourceRoots.setFrom(file("src/main/kotlin"))
classpath.from(sourceSets["main"].runtimeClasspath)
externalDocumentationLink {
url.set(new URL("https://docs.spring.io/spring-framework/docs/current/javadoc-api/"))
}
externalDocumentationLink {
url.set(new URL("https://projectreactor.io/docs/core/release/api/"))
}
externalDocumentationLink {
url.set(new URL("https://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/"))
}
externalDocumentationLink {
url.set(new URL("https://kotlin.github.io/kotlinx.coroutines/"))
}
externalDocumentationLink {
url.set(new URL("https://javadoc.io/doc/org.hamcrest/hamcrest/2.1/"))
}
externalDocumentationLink {
url.set(new URL("https://javadoc.io/doc/javax.servlet/javax.servlet-api/latest/"))
}
externalDocumentationLink {
url.set(new URL("https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/"))
}
}
}
}
-249
View File
@@ -1,249 +0,0 @@
configurations {
asciidoctorExt
}
dependencies {
asciidoctorExt("io.spring.asciidoctor:spring-asciidoctor-extensions-block-switch:0.6.1")
}
repositories {
maven {
url "https://repo.spring.io/release"
mavenContent {
includeGroup "io.spring.asciidoctor"
}
}
}
/**
* Produce Javadoc for all Spring Framework modules in "build/docs/javadoc"
*/
task api(type: Javadoc) {
group = "Documentation"
description = "Generates aggregated Javadoc API documentation."
title = "${rootProject.description} ${version} API"
dependsOn {
moduleProjects.collect {
it.tasks.getByName("jar")
}
}
doFirst {
classpath = files(
// ensure the javadoc process can resolve types compiled from .aj sources
project(":spring-aspects").sourceSets.main.output
)
classpath += files(moduleProjects.collect { it.sourceSets.main.compileClasspath })
}
options {
encoding = "UTF-8"
memberLevel = JavadocMemberLevel.PROTECTED
author = true
header = rootProject.description
use = true
overview = "src/docs/api/overview.html"
stylesheetFile = file("src/docs/api/stylesheet.css")
splitIndex = true
links(project.ext.javadocLinks)
addBooleanOption('Xdoclint:syntax', true) // only check syntax with doclint
addBooleanOption('Xwerror', true) // fail build on Javadoc warnings
if (JavaVersion.current().isJava9Compatible()) {
addBooleanOption('html5', true)
}
}
source moduleProjects.collect { project ->
project.sourceSets.main.allJava
}
maxMemory = "1024m"
destinationDir = file("$buildDir/docs/javadoc")
}
/**
* Produce KDoc for all Spring Framework modules in "build/docs/kdoc"
*/
pluginManager.withPlugin("kotlin") {
tasks.dokkaHtmlMultiModule.configure {
dependsOn {
tasks.getByName("api")
}
moduleName.set("spring-framework")
outputDirectory.set(project.file("$buildDir/docs/kdoc"))
}
}
task downloadResources(type: Download) {
src "https://repo.spring.io/artifactory/snapshot/io/spring/docresources/" +
"spring-doc-resources/0.2.6-SNAPSHOT/spring-doc-resources-0.2.6-20210308.231804-2.zip"
dest project.file("$buildDir/docs/spring-doc-resources.zip")
onlyIfModified true
useETag "all"
}
task extractDocResources(type: Copy, dependsOn: downloadResources) {
from project.zipTree(downloadResources.dest);
into "$buildDir/docs/spring-docs-resources/"
}
asciidoctorj {
def docRoot = 'https://docs.spring.io'
def docsSpringFramework = "${docRoot}/spring-framework/docs/${project.version}"
version = '2.4.1'
fatalWarnings ".*"
options doctype: 'book', eruby: 'erubis'
attributes([
icons: 'font',
idprefix: '',
idseparator: '-',
docinfo: 'shared,private-header', // https://docs.asciidoctor.org/asciidoctor/latest/docinfo/
revnumber: project.version,
sectanchors: '',
sectnums: '',
'source-highlighter': 'highlight.js',
highlightjsdir: 'js/highlight',
'highlightjs-theme': 'googlecode',
stylesdir: 'css/',
stylesheet: 'stylesheet.css',
'spring-version': project.version,
'spring-framework-main-code': 'https://github.com/spring-projects/spring-framework/tree/main',
'doc-root': docRoot,
'docs-spring-framework': docsSpringFramework,
'api-spring-framework': "${docsSpringFramework}/javadoc-api/org/springframework"
])
}
/**
* Generate the Spring Framework Reference documentation from "src/docs/asciidoc"
* in "build/docs/ref-docs/html5".
*/
asciidoctor {
baseDirFollowsSourceDir()
configurations 'asciidoctorExt'
sources {
include '*.adoc'
}
outputDir "$buildDir/docs/ref-docs/html5"
logDocuments = true
resources {
from(sourceDir) {
include 'images/*.png', 'css/**', 'js/**'
}
from extractDocResources
}
}
/**
* Generate the Spring Framework Reference documentation from "src/docs/asciidoc"
* in "build/docs/ref-docs/pdf".
*/
asciidoctorPdf {
baseDirFollowsSourceDir()
configurations 'asciidoctorExt'
sources {
include '*.adoc'
}
outputDir "$buildDir/docs/ref-docs/pdf"
logDocuments = true
}
/**
* Zip all docs (API and reference) into a single archive
*/
task docsZip(type: Zip, dependsOn: ['api', 'asciidoctor', 'asciidoctorPdf', 'dokkaHtmlMultiModule']) {
group = "Distribution"
description = "Builds -${archiveClassifier} archive containing api and reference " +
"for deployment at https://docs.spring.io/spring-framework/docs/."
archiveBaseName.set("spring-framework")
archiveClassifier.set("docs")
from("src/dist") {
include "changelog.txt"
}
from (api) {
into "javadoc-api"
}
from ("$asciidoctor.outputDir") {
into "reference/html"
}
from ("$asciidoctorPdf.outputDir") {
into "reference/pdf"
}
from (dokkaHtmlMultiModule.outputDirectory) {
into "kdoc-api"
}
}
/**
* Zip all Spring Framework schemas into a single archive
*/
task schemaZip(type: Zip) {
group = "Distribution"
archiveBaseName.set("spring-framework")
archiveClassifier.set("schema")
description = "Builds -${archiveClassifier} archive containing all " +
"XSDs for deployment at https://springframework.org/schema."
duplicatesStrategy DuplicatesStrategy.EXCLUDE
moduleProjects.each { module ->
def Properties schemas = new Properties();
module.sourceSets.main.resources.find {
(it.path.endsWith("META-INF/spring.schemas") || it.path.endsWith("META-INF\\spring.schemas"))
}?.withInputStream { schemas.load(it) }
for (def key : schemas.keySet()) {
def shortName = key.replaceAll(/http.*schema.(.*).spring-.*/, '$1')
assert shortName != key
File xsdFile = module.sourceSets.main.resources.find {
(it.path.endsWith(schemas.get(key)) || it.path.endsWith(schemas.get(key).replaceAll('\\/','\\\\')))
}
assert xsdFile != null
into (shortName) {
from xsdFile.path
}
}
}
}
/**
* Create a distribution zip with everything:
* docs, schemas, jars, source jars, javadoc jars
*/
task distZip(type: Zip, dependsOn: [docsZip, schemaZip]) {
group = "Distribution"
archiveBaseName.set("spring-framework")
archiveClassifier.set("dist")
description = "Builds -${archiveClassifier} archive, containing all jars and docs, " +
"suitable for community download page."
ext.baseDir = "spring-framework-${project.version}";
from("src/docs/dist") {
include "readme.txt"
include "license.txt"
include "notice.txt"
into "${baseDir}"
expand(copyright: new Date().format("yyyy"), version: project.version)
}
from(zipTree(docsZip.archiveFile)) {
into "${baseDir}/docs"
}
from(zipTree(schemaZip.archiveFile)) {
into "${baseDir}/schema"
}
moduleProjects.each { module ->
into ("${baseDir}/libs") {
from module.jar
if (module.tasks.findByPath("sourcesJar")) {
from module.sourcesJar
}
if (module.tasks.findByPath("javadocJar")) {
from module.javadocJar
}
}
}
}
distZip.mustRunAfter moduleProjects.check
+59 -50
View File
@@ -1,90 +1,99 @@
import org.gradle.plugins.ide.eclipse.model.ProjectDependency
import org.gradle.plugins.ide.eclipse.model.SourceFolder
apply plugin: 'eclipse'
eclipse.jdt {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
apply plugin: "propdeps-eclipse"
apply plugin: "propdeps-idea"
// Replace classpath entries with project dependencies (GRADLE-1116)
// https://issues.gradle.org/browse/GRADLE-1116
eclipse.classpath.file.whenMerged { classpath ->
def regexp = /.*?\/([^\/]+)\/build\/([^\/]+\/)+(?:main|test)/ // only match those that end in main or test (avoids removing necessary entries like build/classes/jaxb)
def regexp = /.*?\/([^\/]+)\/build\/[^\/]+\/(?:main|test)/ // only match those that end in main or test (avoids removing necessary entries like build/classes/jaxb)
def projectOutputDependencies = classpath.entries.findAll { entry -> entry.path =~ regexp }
projectOutputDependencies.each { entry ->
def matcher = (entry.path =~ regexp)
if (matcher) {
if(matcher) {
def projectName = matcher[0][1]
def path = "/${projectName}"
if (!classpath.entries.find { e -> e instanceof ProjectDependency && e.path == path }) {
def recursiveDependency = entry.path.matches('.+/' + projectName + '/build/([^/]+/)+(?:main|test)')
// Avoid recursive dependency on current project.
if (!recursiveDependency) {
classpath.entries.add(new ProjectDependency(path))
}
if(!classpath.entries.find { e -> e instanceof ProjectDependency && e.path == path }) {
def dependency = new ProjectDependency(path, project(":${projectName}").path)
dependency.exported = true
classpath.entries.add(dependency)
}
classpath.entries.remove(entry)
}
}
// Remove any remaining direct depencencies on JARs in the build/libs folder
// except Spring's spring-cglib-repack and spring-objenesis-repack JARs.
classpath.entries.removeAll { entry -> (entry.path =~ /(?!.*?repack.*\.jar).*?\/([^\/]+)\/build\/libs\/[^\/]+\.jar/) }
}
// Use separate main/test outputs (prevents WTP from packaging test classes)
eclipse.classpath.defaultOutputDir = file(project.name + '/bin/eclipse')
eclipse.classpath.defaultOutputDir = file(project.name+"/bin/eclipse")
eclipse.classpath.file.beforeMerged { classpath ->
classpath.entries.findAll{ it instanceof SourceFolder }.each {
if (it.output.startsWith('bin/')) {
if(it.output.startsWith("bin/")) {
it.output = null
}
}
}
eclipse.classpath.file.whenMerged {
entries.findAll{ it instanceof SourceFolder }.each {
it.output = 'bin/' + it.path.split('/')[1]
eclipse.classpath.file.whenMerged { classpath ->
classpath.entries.findAll{ it instanceof SourceFolder }.each {
it.output = "bin/" + it.path.split("/")[1]
}
}
// Ensure project dependencies come after 3rd-party libs (SPR-11836)
// https://jira.spring.io/browse/SPR-11836
eclipse.classpath.file.whenMerged {
entries.findAll { it instanceof ProjectDependency }.each {
// delete from original position
entries.remove(it)
// append to end of classpath
entries.add(it)
}
}
// Allow projects to be used as WPT modules
eclipse.project.natures "org.eclipse.wst.common.project.facet.core.nature"
// Ensure that JMH sources and resources are treated as test classpath entries
// so that they can see test fixtures.
// https://github.com/melix/jmh-gradle-plugin/issues/157
eclipse.classpath.file.whenMerged {
entries.findAll { it.path =~ /src\/jmh\/(java|resources)/ }.each {
it.entryAttributes['test'] = 'true'
}
}
// Include project specific settings
task eclipseSettings(type: Copy) {
from rootProject.files(
'src/eclipse/org.eclipse.core.resources.prefs',
'src/eclipse/org.eclipse.jdt.core.prefs',
'src/eclipse/org.eclipse.jdt.ui.prefs')
"src/eclipse/org.eclipse.jdt.ui.prefs",
"src/eclipse/org.eclipse.wst.common.project.facet.core.xml")
into project.file('.settings/')
outputs.upToDateWhen { false }
}
task cleanEclipseSettings(type: Delete) {
delete project.file('.settings/org.eclipse.core.resources.prefs')
delete project.file('.settings/org.eclipse.jdt.core.prefs')
delete project.file('.settings/org.eclipse.jdt.ui.prefs')
task eclipseWstComponent(type: Copy) {
from rootProject.files(
"src/eclipse/org.eclipse.wst.common.component")
into project.file('.settings/')
expand(deployname: project.name)
outputs.upToDateWhen { false }
}
tasks['eclipse'].dependsOn(eclipseSettings)
tasks['eclipseJdt'].dependsOn(eclipseSettings)
tasks['cleanEclipse'].dependsOn(cleanEclipseSettings)
task eclipseJdtPrepare(type: Copy) {
from rootProject.file("src/eclipse/org.eclipse.jdt.core.prefs")
into project.file(".settings/")
outputs.upToDateWhen { false }
}
task cleanEclipseJdtUi(type: Delete) {
delete project.file(".settings/org.eclipse.jdt.ui.prefs")
delete project.file("org.eclipse.jdt.core.prefs")
delete project.file(".settings/org.eclipse.wst.common.component")
delete project.file(".settings/org.eclipse.wst.common.project.facet.core.xml")
}
tasks["eclipseJdt"].dependsOn(eclipseJdtPrepare)
tasks["cleanEclipse"].dependsOn(cleanEclipseJdtUi)
tasks["eclipse"].dependsOn(eclipseSettings, eclipseWstComponent)
// Filter 'build' folder
eclipse.project.file.withXml {
def node = it.asNode()
def filteredResources = node.get("filteredResources")
if(filteredResources) {
node.remove(filteredResources)
}
def filterNode = node.appendNode("filteredResources").appendNode("filter")
filterNode.appendNode("id", "1359048889071")
filterNode.appendNode("name", "")
filterNode.appendNode("type", "30")
def matcherNode = filterNode.appendNode("matcher")
matcherNode.appendNode("id", "org.eclipse.ui.ide.multiFilter")
matcherNode.appendNode("arguments", "1.0-projectRelativePath-matches-false-false-build")
}
+75
View File
@@ -0,0 +1,75 @@
/**
* Generate a JDiff report between the current version and an older version.
*
* Usage:
* gradle jdiff -D OLD_VERSION=3.1.3.RELEASE -D OLD_VERSION_ROOT=/path/to/3.1.3.RELEASE
*
* View generated report at:
* build/reports/jdiff/changes.html
*
* @param OLD_VERSION required
* @param OLD_VERSION_ROOT required, typically pointing to a separate git clone dir
*/
task jdiff {
description = "Generates a JDiff report"
group = "Documentation"
def jdiffHome = "${rootProject.rootDir}/gradle/jdiff"
ant.taskdef(
name: "jdiff",
classname: "jdiff.JDiffAntTask",
classpath: "${jdiffHome}/antjdiff.jar")
def currentVersion = rootProject.version
def currentVersionRoot = rootProject.rootDir
def oldVersion = System.getProperty("OLD_VERSION")
def oldVersionRoot = System.getProperty("OLD_VERSION_ROOT")
def outputDir = "${rootProject.buildDir}/reports/jdiff/${oldVersion}_to_${currentVersion}"
doLast {
if (oldVersion == null)
throw new IllegalArgumentException(
"Set OLD_VERSION property to indicate older of the two versions being compared")
if (oldVersionRoot == null)
throw new IllegalArgumentException(
"Set OLD_VERSION_ROOT property to indicate the root directory for ${oldVersion}")
oldVersionRoot = new File(oldVersionRoot)
ant.property(name: "JDIFF_HOME", value: jdiffHome)
ant.mkdir(dir: outputDir)
ant.jdiff(
destdir: outputDir,
verbose: "off",
stats: "on",
docchanges: "off") {
old(name: "Spring Framework ${oldVersion}") {
oldVersionRoot.eachDirMatch( {
def candidate = new File(it)
candidate.name.matches("org.springframework.*") ||
candidate.name.matches("spring-.*") }) { match ->
match.eachDirRecurse { subdir ->
if (subdir.path ==~ '.*/src/main/java$') {
dirset(dir: subdir.path, includes: "org/**")
}
}
}
}
"new"(name: "Spring Framework ${currentVersion}") {
currentVersionRoot.eachDirMatch( {
def candidate = new File(it)
candidate.name.matches("org.springframework.*") ||
candidate.name.matches("spring-.*") }) { match ->
match.eachDirRecurse { subdir ->
if (subdir.path ==~ '.*/src/main/java$') {
dirset(dir: subdir.path, includes: "org/**")
}
}
}
}
}
}
}
+506
View File
@@ -0,0 +1,506 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!
+9
View File
@@ -0,0 +1,9 @@
/**
* This class is used only as a "null" argument for Javadoc when comparing
* two API files. Javadoc has to have a package, .java or .class file as an
* argument, even though JDiff doesn't use it.
*/
public class Null {
public Null() {
}
}
+6
View File
@@ -0,0 +1,6 @@
This distribution of JDiff 1.1.1 is included in the Spring Framework build
because JDiff has a hard requirement on a JDIFF_HOME directory containing
jdiff.jar and xerces.jar as well as other presentation resources.
The actual generation of JDiff reports is driven by the `jdiff` task declared
in build.gradle in the project root.
+59
View File
@@ -0,0 +1,59 @@
JDiff Doclet
------------
Matthew Doar
mdoar@pobox.com
The JDiff doclet is used to generate a report describing the
difference between two public Java APIs.
The file jdiff.html contains the reference page for JDiff. The latest
version of JDiff can be downloaded at:
http://sourceforge.net/projects/javadiff
To use the Ant task on your own project, see example.xml. More examples
of using JDiff to compare the public APIs of J2SE1.3 and J2SE1.4 can
be seen at http://www.jdiff.org
For an example with the source distribution, run "ant" and
look at the HTML output in ./build/reports/example/changes.html
The page at ./build/reports/example/changes/com.acme.sp.SPImpl.html
shows what a typical page of changes looks like.
System Requirements
-------------------
JDiff has been tested with all releases of Java since J2SE1.2 but
releases of JDiff after 1.10.0 focus on JDK1.5.
License
-------
JDiff is licensed under the Lesser GNU General Public License (LGPL).
See the file LICENSE.txt.
Acknowledgements
----------------
JDiff uses Stuart D. Gathman's Java translation of Gene Myers' O(ND)
difference algorithm.
JDiff uses Xerces 1.4.2 from http://www.apache.org.
JDiff also includes a script to use the classdoc application from
http://classdoc.sourceforge.net or http://www.jensgulden.de, by Jens
Gulden, (mail@jensgulden.de), to call a doclet such as jdiff on a .jar
file rather than on source.
Many thanks to the reviewers at Sun and Vitria who gave feedback on early
versions of JDiff output, and also to the distillers of Laphroaig, and to
Arturo Fuente for his consistently fine cigars which helped inspire
much of this work.
Footnote:
If you are looking for a generalized diff tool for XML, try diffmk from
http://wwws.sun.com/software/xml/developers/diffmk/
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 559 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 799 B

File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 B

Binary file not shown.
-64
View File
@@ -1,64 +0,0 @@
apply plugin: "maven-publish"
publishing {
publications {
mavenJava(MavenPublication) {
pom {
afterEvaluate {
name = project.description
description = project.description
}
url = "https://github.com/spring-projects/spring-framework"
organization {
name = "Spring IO"
url = "https://spring.io/projects/spring-framework"
}
licenses {
license {
name = "Apache License, Version 2.0"
url = "https://www.apache.org/licenses/LICENSE-2.0"
distribution = "repo"
}
}
scm {
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@pivotal.io"
}
}
issueManagement {
system = "GitHub"
url = "https://github.com/spring-projects/spring-framework/issues"
}
}
versionMapping {
usage('java-api') {
fromResolutionResult()
}
usage('java-runtime') {
fromResolutionResult()
}
}
}
}
}
configureDeploymentRepository(project)
void configureDeploymentRepository(Project project) {
project.plugins.withType(MavenPublishPlugin.class).all {
PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class);
if (project.hasProperty("deploymentRepository")) {
publishing.repositories.maven {
it.url = project.property("deploymentRepository")
it.name = "deployment"
}
}
}
}
+51
View File
@@ -0,0 +1,51 @@
apply plugin: "propdeps-maven"
install {
repositories.mavenInstaller {
customizePom(pom, project)
}
}
def customizePom(pom, gradleProject) {
pom.whenConfigured { generatedPom ->
// eliminate test-scoped dependencies (no need in maven central poms)
generatedPom.dependencies.removeAll { dep ->
dep.scope == "test"
}
// sort to make pom dependencies order consistent to ease comparison of older poms
generatedPom.dependencies = generatedPom.dependencies.sort { dep ->
"$dep.scope:$dep.groupId:$dep.artifactId"
}
// add all items necessary for maven central publication
generatedPom.project {
name = gradleProject.description
description = gradleProject.description
url = "https://github.com/SpringSource/spring-framework"
organization {
name = "SpringSource"
url = "http://springsource.org/spring-framework"
}
licenses {
license {
name "The Apache Software License, Version 2.0"
url "http://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"
}
developers {
developer {
id = "jhoeller"
name = "Juergen Hoeller"
email = "jhoeller@gopivotal.com"
}
}
}
}
}
-102
View File
@@ -1,102 +0,0 @@
apply plugin: 'java-library'
apply plugin: 'org.springframework.build.compile'
apply plugin: 'org.springframework.build.optional-dependencies'
// Uncomment the following for Shadow support in the jmhJar block.
// Currently commented out due to ZipException: archive is not a ZIP archive
// apply plugin: 'com.github.johnrengelman.shadow'
apply plugin: 'me.champeau.jmh'
apply from: "$rootDir/gradle/publications.gradle"
dependencies {
jmh 'org.openjdk.jmh:jmh-core:1.32'
jmh 'org.openjdk.jmh:jmh-generator-annprocess:1.32'
jmh 'net.sf.jopt-simple:jopt-simple'
}
jmh {
duplicateClassesStrategy = DuplicatesStrategy.EXCLUDE
}
tasks.findByName("processJmhResources").configure {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
jmhJar {
// Uncomment the following for Shadow's Transformer support.
// mergeServiceFiles()
// append('META-INF/spring.handlers')
// append('META-INF/spring.schemas')
// append('META-INF/spring.tooling')
exclude 'LICENSE'
exclude 'THIRD-PARTY'
exclude 'META-INF/license.txt'
exclude 'META-INF/notice.txt'
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE*'
exclude 'META-INF/NOTICE'
exclude 'META-INF/THIRD-PARTY'
}
jar {
manifest.attributes["Implementation-Title"] = project.name
manifest.attributes["Implementation-Version"] = project.version
manifest.attributes["Automatic-Module-Name"] = project.name.replace('-', '.') // for Jigsaw
manifest.attributes["Created-By"] =
"${System.getProperty("java.version")} (${System.getProperty("java.specification.vendor")})"
from("${rootDir}/src/docs/dist") {
include "license.txt"
include "notice.txt"
into "META-INF"
expand(copyright: new Date().format("yyyy"), version: project.version)
}
}
normalization {
runtimeClasspath {
ignore "META-INF/MANIFEST.MF"
}
}
javadoc {
description = "Generates project-level javadoc for use in -javadoc jar"
options.encoding = "UTF-8"
options.memberLevel = JavadocMemberLevel.PROTECTED
options.author = true
options.header = project.name
options.use = true
options.links(project.ext.javadocLinks)
options.addStringOption("Xdoclint:none", "-quiet")
// Suppress warnings due to cross-module @see and @link references.
// Note that global 'api' task does display all warnings.
logging.captureStandardError LogLevel.INFO
logging.captureStandardOutput LogLevel.INFO // suppress "## warnings" message
}
task sourcesJar(type: Jar, dependsOn: classes) {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
archiveClassifier.set("sources")
from sourceSets.main.allSource
// Don't include or exclude anything explicitly by default. See SPR-12085.
}
task javadocJar(type: Jar) {
archiveClassifier.set("javadoc")
from javadoc
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
artifact sourcesJar
artifact javadocJar
}
}
}
// Disable publication of test fixture artifacts.
components.java.withVariantsFromConfiguration(configurations.testFixturesApiElements) { skip() }
components.java.withVariantsFromConfiguration(configurations.testFixturesRuntimeElements) { skip() }
-171
View File
@@ -1,171 +0,0 @@
/**
* Apply the JVM Toolchain conventions
* See https://docs.gradle.org/current/userguide/toolchains.html
*
* One can choose the toolchain to use for compiling the MAIN sources and/or compiling
* and running the TEST sources. These options apply to Java, Kotlin and Groovy sources
* when available.
* {@code "./gradlew check -PmainToolchain=8 -PtestToolchain=11"} will use:
* <ul>
* <li>a JDK8 toolchain for compiling the main SourceSet
* <li>a JDK11 toolchain for compiling and running the test SourceSet
* </ul>
*
* By default, the build will fall back to using the current JDK and 1.8 language level for all sourceSets.
*
* Gradle will automatically detect JDK distributions in well-known locations.
* The following command will list the detected JDKs on the host.
* {@code
* $ ./gradlew -q javaToolchains
* }
*
* We can also configure ENV variables and let Gradle know about them:
* {@code
* $ echo JDK11
* /opt/openjdk/java11
* $ echo JDK15
* /opt/openjdk/java15
* $ ./gradlew -Porg.gradle.java.installations.fromEnv=JDK11,JDK15 check
* }
*
* @author Brian Clozel
* @author Sam Brannen
*/
def mainToolchainConfigured() {
return project.hasProperty('mainToolchain') && project.mainToolchain
}
def testToolchainConfigured() {
return project.hasProperty('testToolchain') && project.testToolchain
}
def mainToolchainLanguageVersion() {
if (mainToolchainConfigured()) {
return JavaLanguageVersion.of(project.mainToolchain.toString())
}
return JavaLanguageVersion.of(8)
}
def testToolchainLanguageVersion() {
if (testToolchainConfigured()) {
return JavaLanguageVersion.of(project.testToolchain.toString())
}
return mainToolchainLanguageVersion()
}
plugins.withType(JavaPlugin) {
// Configure the Java Toolchain if the 'mainToolchain' is configured
if (mainToolchainConfigured()) {
java {
toolchain {
languageVersion = mainToolchainLanguageVersion()
}
}
}
else {
// Fallback to JDK8
java {
sourceCompatibility = JavaVersion.VERSION_1_8
}
}
// Configure a specific Java Toolchain for compiling and running tests if the 'testToolchain' property is defined
if (testToolchainConfigured()) {
def testLanguageVersion = testToolchainLanguageVersion()
tasks.withType(JavaCompile).matching { it.name.contains("Test") }.configureEach {
javaCompiler = javaToolchains.compilerFor {
languageVersion = testLanguageVersion
}
}
tasks.withType(Test).configureEach{
javaLauncher = javaToolchains.launcherFor {
languageVersion = testLanguageVersion
}
if(testLanguageVersion == JavaLanguageVersion.of(17)) {
jvmArgs(["--add-opens=java.base/java.lang=ALL-UNNAMED",
"--add-opens=java.base/java.util=ALL-UNNAMED"])
}
}
}
}
plugins.withType(GroovyPlugin) {
// Fallback to JDK8
if (!mainToolchainConfigured()) {
compileGroovy {
sourceCompatibility = JavaVersion.VERSION_1_8
}
}
}
pluginManager.withPlugin("kotlin") {
// Configure the Kotlin compiler if the 'mainToolchain' property is defined
if (mainToolchainConfigured()) {
def mainLanguageVersion = mainToolchainLanguageVersion()
def compiler = javaToolchains.compilerFor {
languageVersion = mainLanguageVersion
}
// See https://kotlinlang.org/docs/gradle.html#attributes-specific-for-jvm
def javaVersion = mainLanguageVersion.toString() == '8' ? '1.8' : mainLanguageVersion.toString()
compileKotlin {
kotlinOptions {
jvmTarget = javaVersion
jdkHome = compiler.get().metadata.installationPath.asFile.absolutePath
}
}
// Compile the test classes with the same version, 'testToolchain' will override if defined
compileTestKotlin {
kotlinOptions {
jvmTarget = javaVersion
jdkHome = compiler.get().metadata.installationPath.asFile.absolutePath
}
}
}
else {
// Fallback to JDK8
compileKotlin {
kotlinOptions {
jvmTarget = '1.8'
}
}
compileTestKotlin {
kotlinOptions {
jvmTarget = '1.8'
}
}
}
}
// Configure the JMH plugin to use the toolchain for generating and running JMH bytecode
pluginManager.withPlugin("me.champeau.jmh") {
if (mainToolchainConfigured() || testToolchainConfigured()) {
tasks.matching { it.name.contains('jmh') && it.hasProperty('javaLauncher') }.configureEach {
javaLauncher.set(javaToolchains.launcherFor {
languageVersion.set(testToolchainLanguageVersion())
})
}
tasks.withType(JavaCompile).matching { it.name.contains("Jmh") }.configureEach {
javaCompiler = javaToolchains.compilerFor {
languageVersion = testToolchainLanguageVersion()
}
}
}
}
// Store resolved Toolchain JVM information as custom values in the build scan.
rootProject.ext {
resolvedMainToolchain = false
resolvedTestToolchain = false
}
gradle.taskGraph.afterTask { Task task, TaskState state ->
if (mainToolchainConfigured() && !resolvedMainToolchain && task instanceof JavaCompile && task.javaCompiler.isPresent()) {
def metadata = task.javaCompiler.get().metadata
task.project.buildScan.value('Main toolchain', "$metadata.vendor $metadata.languageVersion ($metadata.installationPath)")
resolvedMainToolchain = true
}
if (testToolchainConfigured() && !resolvedTestToolchain && task instanceof Test && task.javaLauncher.isPresent()) {
def metadata = task.javaLauncher.get().metadata
task.project.buildScan.value('Test toolchain', "$metadata.vendor $metadata.languageVersion ($metadata.installationPath)")
resolvedTestToolchain = true
}
}
Binary file not shown.
+4 -3
View File
@@ -1,5 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
#Tue Jul 30 09:29:28 PDT 2013
zipStoreBase=GRADLE_USER_HOME
distributionUrl=http\://services.gradle.org/distributions/gradle-1.6-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
distributionBase=GRADLE_USER_HOME
Vendored
+115 -184
View File
@@ -1,129 +1,80 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original 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
#
# https://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.
#
#!/usr/bin/env bash
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
GRADLE_OPTS="-XX:MaxPermSize=1024m -Xmx1024m $GRADLE_OPTS"
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
MAX_FD="maximum"
warn () {
warn ( ) {
echo "$*"
} >&2
}
die () {
die ( ) {
echo
echo "$*"
echo
exit 1
} >&2
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD=$JAVA_HOME/bin/java
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -132,7 +83,7 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
@@ -140,95 +91,75 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
exec "$JAVACMD" "$@"
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
Vendored
+28 -26
View File
@@ -1,19 +1,3 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@@ -24,23 +8,21 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set GRADLE_OPTS=-XX:MaxPermSize=1024m -Xmx1024m -XX:MaxHeapSize=256m %GRADLE_OPTS%
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -54,7 +36,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -64,14 +46,34 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
+117
View File
@@ -0,0 +1,117 @@
@echo off
set STS_TEST_VERSION='2.9.2.RELEASE'
set CURRENT_DIR=%~dp0
cd %CURRENT_DIR%
cls
echo.
echo -----------------------------------------------------------------------
echo Spring Framework Eclipse/STS project import guide
echo.
echo This script will guide you through the process of importing the
echo Spring Framework sources into Eclipse/STS. It is recommended that you
echo have a recent version of the SpringSource Tool Suite (this script has
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://springsource.org/downloads/sts
echo.
echo Otherwise, press enter and we'll begin.
pause
REM this command:
REM - wipes out any existing Eclipse metadata
REM - generates OXM test classes to avoid errors on import into Eclipse
REM - generates metadata for all subprojects
REM - skips metadata gen for the root project (-x :eclipse) to work
REM around Eclipse's inability to import hierarchical project structures
REM SET COMMAND="./gradlew cleanEclipse :spring-oxm:compileTestJava eclipse -x :eclipse"
SET COMMAND=gradlew cleanEclipse :spring-oxm:compileTestJava eclipse -x :eclipse
echo.
echo -----------------------------------------------------------------------
echo STEP 1: Generate subproject Eclipse metadata
echo.
echo The first step will be to generate Eclipse project metadata for each
echo of the spring-* subprojects. This happens via the built-in
echo "Gradle wrapper" script (./gradlew in this directory). If this is your
echo first time using the Gradle wrapper, this step may take a few minutes
echo while a Gradle distribution is downloaded for you.
echo.
echo The command run will be:
echo.
echo %COMMAND%
echo.
echo Press enter when ready.
pause
call %COMMAND%
if not "%ERRORLEVEL%" == "0" exit /B %ERRORLEVEL%
echo.
echo -----------------------------------------------------------------------
echo STEP 2: Import subprojects into Eclipse/STS
echo.
echo Within Eclipse/STS, do the following:
echo.
echo File ^> Import... ^> Existing Projects into Workspace
echo ^> When prompted for the 'root directory', provide %CURRENT_DIR%
echo ^> Press enter. You will see the modules show up under "Projects"
echo ^> All projects should be selected/checked. Click Finish.
echo ^> When the project import is complete, you should have no errors.
echo.
echo When the above is complete, return here and press the enter key.
pause
set COMMAND=gradlew :eclipse
echo.
echo -----------------------------------------------------------------------
echo STEP 3: generate root project Eclipse metadata
echo.
echo Unfortunately, Eclipse does not allow for importing project
echo hierarchies, so we had to skip root project metadata generation in the
echo during step 1. In this step we simply generate root project metadata
echo so you can import it in the next step.
echo.
echo The command run will be:
echo.
echo %COMMAND%
echo.
echo Press the enter key when ready.
pause
call %COMMAND%
if not "%ERRORLEVEL%" == "0" exit /B %ERRORLEVEL%
echo.
echo -----------------------------------------------------------------------
echo STEP 4: Import root project into Eclipse/STS
echo.
echo Follow the project import steps listed in step 2 above to import the
echo root project.
echo.
echo Press enter when complete, and move on to the final step.
pause
echo.
echo -----------------------------------------------------------------------
echo STEP 5: Enable Git support for all projects
echo.
echo - In the Eclipse/STS Package Explorer, select all spring* projects.
echo - Right-click to open the context menu and select Team ^> Share Project...
echo - In the Share Project dialog that appears, select Git and press Next
echo - Check "Use or create repository in parent folder of project"
echo - Click Finish
echo.
echo When complete, you'll have Git support enabled for all projects.
echo.
echo You're ready to code! Goodbye!
-56
View File
@@ -1,56 +0,0 @@
# Spring Framework - Eclipse/STS Project Import Guide
This document will guide you through the process of importing the Spring Framework
projects into Eclipse or the Spring Tool Suite (_STS_). It is recommended that you
have a recent version of Eclipse. As a bare minimum you will need Eclipse with full Java
8 support, Eclipse Buildship, and the Groovy plugin.
The following instructions have been tested against [STS](https://spring.io/tools) 4.12.0
([download](https://github.com/spring-projects/sts4/wiki/Previous-Versions#spring-tools-4120-changelog))
(based on Eclipse 4.21) with [Eclipse Buildship](https://projects.eclipse.org/projects/tools.buildship).
The instructions should work with the latest Eclipse distribution as long as you install
[Buildship](https://marketplace.eclipse.org/content/buildship-gradle-integration). Note
that STS 4 comes with Buildship preinstalled.
## Steps
_When instructed to execute `./gradlew` from the command line, be sure to execute it within your locally cloned `spring-framework` working directory._
1. Install the [Groovy Development Tools](https://marketplace.eclipse.org/content/groovy-development-tools).
1. Switch to Groovy 3.0 in Eclipse (Preferences &#8594; Groovy &#8594; Compiler &#8594; Switch to 3.0...).
- If you encounter build errors stating something similar to _"Groovy: compiler mismatch: project level is 2.5, workspace level is 3.0"_, change the Groovy compiler version to 3.0 for each affected project.
1. Ensure that the _Forbidden reference (access rule)_ in Eclipse is set to `Info`
(Preferences &#8594; Java &#8594; Compiler &#8594; Errors/Warnings &#8594; Deprecated and restricted API &#8594; Forbidden reference (access rule)).
1. Optionally install the [Kotlin Plugin for Eclipse](https://marketplace.eclipse.org/content/kotlin-plugin-eclipse) if you need to execute Kotlin-based tests or develop Kotlin extensions.
- **NOTE**: As of September 21, 2021, it appears that the Kotlin Plugin for Eclipse does not yet work with Eclipse 4.21.
1. Optionally install the [AspectJ Development Tools](https://marketplace.eclipse.org/content/aspectj-development-tools) (_AJDT_) if you need to work with the `spring-aspects` project.
- **NOTE**: As of September 21, 2021, it appears that the AspectJ Development Tools do not yet work with Eclipse 4.21.
1. Optionally install the [TestNG plugin](https://testng.org/doc/eclipse.html) in Eclipse if you need to execute individual TestNG test classes or tests in the `spring-test` module.
- As an alternative to installing the TestNG plugin, you can execute the `org.springframework.test.context.testng.TestNGTestSuite` class as a "JUnit 5" test class in Eclipse.
1. Build `spring-oxm` from the command line with `./gradlew :spring-oxm:check`.
1. To apply Spring Framework specific settings, run `./gradlew cleanEclipse eclipse` from the command line.
1. Import all projects into Eclipse (File &#8594; Import &#8594; Gradle &#8594; Existing Gradle Project &#8594; Navigate to the locally cloned `spring-framework` directory &#8594; Select Finish).
- If you have not installed AJDT, exclude the `spring-aspects` project from the import, if prompted, or close it after the import.
- If you run into errors during the import, you may need to set the _Java home_ for Gradle Buildship to the location of your JDK 8 installation in Eclipse (Preferences &#8594; Gradle &#8594; Java home).
1. If you need to execute JAXB-related tests in the `spring-oxm` project and wish to have the generated sources available, add the `build/generated-sources/jaxb` folder to the build path (right click on the `jaxb` folder and select "Build Path &#8594; Use as Source Folder").
- If you do not see the `build` folder in the `spring-oxm` project, ensure that the "Gradle build folder" is not filtered out from the view. This setting is available under "Filters" in the configuration of the Package Explorer (available by clicking on the _three vertical dots_ in the upper right corner of the Package Explorer).
1. Code away!
## Known Issues
1. `spring-core` should be pre-compiled due to repackaged dependencies.
- See `*RepackJar` tasks in the `spring-core.gradle` build file.
1. `spring-oxm` should be pre-compiled due to JAXB types generated for tests.
- Note that executing `./gradlew :spring-oxm:check` as explained in the _Steps_ above will compile `spring-core` and generate JAXB types for `spring-oxm`.
1. `spring-aspects` does not compile due to references to aspect types unknown to Eclipse.
- If you installed _AJDT_ into Eclipse it should work.
1. While JUnit tests pass from the command line with Gradle, some may fail when run from
the IDE.
- Resolving this is a work in progress.
- If attempting to run all JUnit tests from within the IDE, you may need to set the following VM options to avoid out of memory errors: `-XX:MaxPermSize=2048m -Xmx2048m -XX:MaxHeapSize=2048m`
## Tips
In any case, please do not check in your own generated `.classpath` file, `.project`
file, or `.settings` folder. You'll notice these files are already intentionally in
`.gitignore`. The same policy holds for IDEA metadata.
+120
View File
@@ -0,0 +1,120 @@
STS_TEST_VERSION='2.9.2.RELEASE'
cd `dirname $0`
clear
cat <<EOM
-----------------------------------------------------------------------
Spring Framework Eclipse/STS project import guide
This script will guide you through the process of importing the
Spring Framework sources into Eclipse/STS. It is recommended that you
have a recent version of the SpringSource Tool Suite (this script has
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://springsource.org/downloads/sts
Otherwise, press enter and we'll begin.
EOM
read
# this command:
# - wipes out any existing Eclipse metadata
# - generates OXM test classes to avoid errors on import into Eclipse
# - generates metadata for all subprojects
# - skips metadata gen for the root project (-x :eclipse) to work
# around Eclipse's inability to import hierarchical project structures
COMMAND="./gradlew cleanEclipse :spring-oxm:compileTestJava eclipse -x :eclipse"
cat <<EOM
-----------------------------------------------------------------------
STEP 1: Generate subproject Eclipse metadata
The first step will be to generate Eclipse project metadata for each
of the spring-* subprojects. This happens via the built-in
"Gradle wrapper" script (./gradlew in this directory). If this is your
first time using the Gradle wrapper, this step may take a few minutes
while a Gradle distribution is downloaded for you.
The command run will be:
$COMMAND
Press enter when ready.
EOM
read
$COMMAND || exit
cat <<EOM
-----------------------------------------------------------------------
STEP 2: Import subprojects into Eclipse/STS
Within Eclipse/STS, do the following:
File > Import... > Existing Projects into Workspace
> When prompted for the 'root directory', provide $PWD
> Press enter. You will see the modules show up under "Projects"
> All projects should be selected/checked. Click Finish.
> When the project import is complete, you should have no errors.
When the above is complete, return here and press the enter key.
EOM
read
COMMAND="./gradlew :eclipse"
cat <<EOM
-----------------------------------------------------------------------
STEP 3: generate root project Eclipse metadata
Unfortunately, Eclipse does not allow for importing project
hierarchies, so we had to skip root project metadata generation in the
during step 1. In this step we simply generate root project metadata
so you can import it in the next step.
The command run will be:
$COMMAND
Press the enter key when ready.
EOM
read
$COMMAND || exit
cat <<EOM
-----------------------------------------------------------------------
STEP 4: Import root project into Eclipse/STS
Follow the project import steps listed in step 2 above to import the
root project.
Press enter when complete, and move on to the final step.
EOM
read
cat <<EOM
-----------------------------------------------------------------------
STEP 5: Enable Git support for all projects
- In the Eclipse/STS Package Explorer, select all spring* projects.
- Right-click to open the context menu and select Team > Share Project...
- In the Share Project dialog that appears, select Git and press Next
- Check "Use or create repository in parent folder of project"
- Click Finish
When complete, you'll have Git support enabled for all projects.
You're ready to code! Goodbye!
EOM
+14 -18
View File
@@ -1,28 +1,24 @@
The following has been tested against IntelliJ IDEA 2016.2.2
The following has been tested against Intellij IDEA 12.0
## Steps
_Within your locally cloned spring-framework working directory:_
1. Precompile `spring-oxm` with `./gradlew :spring-oxm:compileTestJava`
2. Import into IntelliJ (File -> New -> Project from Existing Sources -> Navigate to directory -> Select build.gradle)
3. When prompted exclude the `spring-aspects` module (or after the import via File-> Project Structure -> Modules)
4. Code away
1. Generate IDEA metadata with `./gradlew :spring-oxm:compileTestJava cleanIdea idea`
2. Import into IDEA as usual
3. Set the Project JDK as appropriate
4. Add git support
5. Code away
## Known issues
1. `spring-core` and `spring-oxm` should be pre-compiled due to repackaged dependencies.
See `*RepackJar` tasks in the build and https://youtrack.jetbrains.com/issue/IDEA-160605).
2. `spring-aspects` does not compile due to references to aspect types unknown to
IntelliJ IDEA. See https://youtrack.jetbrains.com/issue/IDEA-64446 for details. In the meantime, the
'spring-aspects' can be excluded from the project to avoid compilation errors.
3. While JUnit tests pass from the command line with Gradle, some may fail when run from
IntelliJ IDEA. Resolving this is a work in progress. If attempting to run all JUnit tests from within
IntelliJ IDEA, you will likely need to set the following VM options to avoid out of memory errors:
1. `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.
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
4. If you invoke "Rebuild Project" in the IDE, you'll have to generate some test
resources of the `spring-oxm` module again (`./gradlew :spring-oxm:compileTestJava`)
## Tips
@@ -31,6 +27,6 @@ You'll notice these files are already intentionally in .gitignore. The same poli
## FAQ
Q. What about IntelliJ IDEA's own [Gradle support](https://www.jetbrains.com/help/idea/gradle.html)?
Q. What about IDEA's own [Gradle support](http://confluence.jetbrains.net/display/IDEADEV/Gradle+integration)?
A. Keep an eye on https://youtrack.jetbrains.com/issue/IDEA-53476
A. Keep an eye on http://youtrack.jetbrains.com/issue/IDEA-53476
@@ -1,30 +0,0 @@
description = "Spring Integration Tests"
dependencies {
testImplementation(project(":spring-aop"))
testImplementation(project(":spring-beans"))
testImplementation(project(":spring-context"))
testImplementation(project(":spring-core"))
testImplementation(testFixtures(project(":spring-aop")))
testImplementation(testFixtures(project(":spring-beans")))
testImplementation(testFixtures(project(":spring-core")))
testImplementation(testFixtures(project(":spring-tx")))
testImplementation(project(":spring-expression"))
testImplementation(project(":spring-jdbc"))
testImplementation(project(":spring-orm"))
testImplementation(project(":spring-test"))
testImplementation(project(":spring-tx"))
testImplementation(project(":spring-web"))
testImplementation("javax.inject:javax.inject")
testImplementation("javax.resource:javax.resource-api")
testImplementation("javax.servlet:javax.servlet-api")
testImplementation("org.aspectj:aspectjweaver")
testImplementation("org.hsqldb:hsqldb")
testImplementation("org.hibernate:hibernate-core")
}
normalization {
runtimeClasspath {
ignore "META-INF/MANIFEST.MF"
}
}
@@ -1,119 +0,0 @@
/*
* Copyright 2002-2022 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
*
* https://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.aop.config;
import java.util.ArrayList;
import java.util.List;
import org.aspectj.lang.ProceedingJoinPoint;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatException;
/**
* Integration tests for advice invocation order for advice configured via the
* AOP namespace.
*
* @author Sam Brannen
* @since 5.2.7
* @see org.springframework.aop.framework.autoproxy.AspectJAutoProxyAdviceOrderIntegrationTests
*/
class AopNamespaceHandlerAdviceOrderIntegrationTests {
@Nested
@SpringJUnitConfig(locations = "AopNamespaceHandlerAdviceOrderIntegrationTests-afterFirst.xml")
@DirtiesContext
class AfterAdviceFirstTests {
@Test
void afterAdviceIsInvokedFirst(@Autowired Echo echo, @Autowired InvocationTrackingAspect aspect) throws Exception {
assertThat(aspect.invocations).isEmpty();
assertThat(echo.echo(42)).isEqualTo(42);
assertThat(aspect.invocations).containsExactly("around - start", "before", "around - end", "after", "after returning");
aspect.invocations.clear();
assertThatException().isThrownBy(() -> echo.echo(new Exception()));
assertThat(aspect.invocations).containsExactly("around - start", "before", "around - end", "after", "after throwing");
}
}
@Nested
@SpringJUnitConfig(locations = "AopNamespaceHandlerAdviceOrderIntegrationTests-afterLast.xml")
@DirtiesContext
class AfterAdviceLastTests {
@Test
void afterAdviceIsInvokedLast(@Autowired Echo echo, @Autowired InvocationTrackingAspect aspect) throws Exception {
assertThat(aspect.invocations).isEmpty();
assertThat(echo.echo(42)).isEqualTo(42);
assertThat(aspect.invocations).containsExactly("around - start", "before", "around - end", "after returning", "after");
aspect.invocations.clear();
assertThatException().isThrownBy(() -> echo.echo(new Exception()));
assertThat(aspect.invocations).containsExactly("around - start", "before", "around - end", "after throwing", "after");
}
}
static class Echo {
Object echo(Object obj) throws Exception {
if (obj instanceof Exception) {
throw (Exception) obj;
}
return obj;
}
}
static class InvocationTrackingAspect {
List<String> invocations = new ArrayList<>();
Object around(ProceedingJoinPoint joinPoint) throws Throwable {
invocations.add("around - start");
try {
return joinPoint.proceed();
}
finally {
invocations.add("around - end");
}
}
void before() {
invocations.add("before");
}
void afterReturning() {
invocations.add("after returning");
}
void afterThrowing() {
invocations.add("after throwing");
}
void after() {
invocations.add("after");
}
}
}
@@ -1,137 +0,0 @@
/*
* Copyright 2002-2019 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
*
* https://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.aop.config;
import org.junit.jupiter.api.Test;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.testfixture.beans.ITestBean;
import org.springframework.beans.testfixture.beans.TestBean;
import org.springframework.core.testfixture.io.SerializationTestUtils;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for scoped proxy use in conjunction with aop: namespace.
* Deemed an integration test because .web mocks and application contexts are required.
*
* @author Rob Harrop
* @author Juergen Hoeller
* @author Chris Beams
* @see org.springframework.aop.config.AopNamespaceHandlerTests
*/
@SpringJUnitWebConfig
class AopNamespaceHandlerScopeIntegrationTests {
@Autowired
ITestBean singletonScoped;
@Autowired
ITestBean requestScoped;
@Autowired
ITestBean sessionScoped;
@Autowired
ITestBean sessionScopedAlias;
@Autowired
ITestBean testBean;
@Test
void testSingletonScoping() throws Exception {
assertThat(AopUtils.isAopProxy(singletonScoped)).as("Should be AOP proxy").isTrue();
boolean condition = singletonScoped instanceof TestBean;
assertThat(condition).as("Should be target class proxy").isTrue();
String rob = "Rob Harrop";
String bram = "Bram Smeets";
assertThat(singletonScoped.getName()).isEqualTo(rob);
singletonScoped.setName(bram);
assertThat(singletonScoped.getName()).isEqualTo(bram);
ITestBean deserialized = SerializationTestUtils.serializeAndDeserialize(singletonScoped);
assertThat(deserialized.getName()).isEqualTo(bram);
}
@Test
void testRequestScoping() throws Exception {
MockHttpServletRequest oldRequest = new MockHttpServletRequest();
MockHttpServletRequest newRequest = new MockHttpServletRequest();
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(oldRequest));
assertThat(AopUtils.isAopProxy(requestScoped)).as("Should be AOP proxy").isTrue();
boolean condition = requestScoped instanceof TestBean;
assertThat(condition).as("Should be target class proxy").isTrue();
assertThat(AopUtils.isAopProxy(testBean)).as("Should be AOP proxy").isTrue();
boolean condition1 = testBean instanceof TestBean;
assertThat(condition1).as("Regular bean should be JDK proxy").isFalse();
String rob = "Rob Harrop";
String bram = "Bram Smeets";
assertThat(requestScoped.getName()).isEqualTo(rob);
requestScoped.setName(bram);
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(newRequest));
assertThat(requestScoped.getName()).isEqualTo(rob);
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(oldRequest));
assertThat(requestScoped.getName()).isEqualTo(bram);
assertThat(((Advised) requestScoped).getAdvisors().length > 0).as("Should have advisors").isTrue();
}
@Test
void testSessionScoping() throws Exception {
MockHttpSession oldSession = new MockHttpSession();
MockHttpSession newSession = new MockHttpSession();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setSession(oldSession);
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));
assertThat(AopUtils.isAopProxy(sessionScoped)).as("Should be AOP proxy").isTrue();
boolean condition1 = sessionScoped instanceof TestBean;
assertThat(condition1).as("Should not be target class proxy").isFalse();
assertThat(sessionScopedAlias).isSameAs(sessionScoped);
assertThat(AopUtils.isAopProxy(testBean)).as("Should be AOP proxy").isTrue();
boolean condition = testBean instanceof TestBean;
assertThat(condition).as("Regular bean should be JDK proxy").isFalse();
String rob = "Rob Harrop";
String bram = "Bram Smeets";
assertThat(sessionScoped.getName()).isEqualTo(rob);
sessionScoped.setName(bram);
request.setSession(newSession);
assertThat(sessionScoped.getName()).isEqualTo(rob);
request.setSession(oldSession);
assertThat(sessionScoped.getName()).isEqualTo(bram);
assertThat(((Advised) sessionScoped).getAdvisors().length > 0).as("Should have advisors").isTrue();
}
}
@@ -1,318 +0,0 @@
/*
* Copyright 2002-2019 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
*
* https://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.aop.framework.autoproxy;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.List;
import javax.servlet.ServletException;
import org.junit.jupiter.api.Test;
import org.springframework.aop.support.AopUtils;
import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;
import org.springframework.aop.testfixture.advice.CountingBeforeAdvice;
import org.springframework.aop.testfixture.advice.MethodCounter;
import org.springframework.aop.testfixture.interceptor.NopInterceptor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.testfixture.beans.ITestBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.lang.Nullable;
import org.springframework.transaction.NoTransactionException;
import org.springframework.transaction.interceptor.TransactionInterceptor;
import org.springframework.transaction.testfixture.CallCountingTransactionManager;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for auto proxy creation by advisor recognition working in
* conjunction with transaction management resources.
*
* @see org.springframework.aop.framework.autoproxy.AdvisorAutoProxyCreatorTests
*
* @author Rod Johnson
* @author Chris Beams
*/
class AdvisorAutoProxyCreatorIntegrationTests {
private static final Class<?> CLASS = AdvisorAutoProxyCreatorIntegrationTests.class;
private static final String CLASSNAME = CLASS.getSimpleName();
private static final String DEFAULT_CONTEXT = CLASSNAME + "-context.xml";
private static final String ADVISOR_APC_BEAN_NAME = "aapc";
private static final String TXMANAGER_BEAN_NAME = "txManager";
/**
* Return a bean factory with attributes and EnterpriseServices configured.
*/
protected BeanFactory getBeanFactory() throws IOException {
return new ClassPathXmlApplicationContext(DEFAULT_CONTEXT, CLASS);
}
@Test
void testDefaultExclusionPrefix() throws Exception {
DefaultAdvisorAutoProxyCreator aapc = (DefaultAdvisorAutoProxyCreator) getBeanFactory().getBean(ADVISOR_APC_BEAN_NAME);
assertThat(aapc.getAdvisorBeanNamePrefix()).isEqualTo((ADVISOR_APC_BEAN_NAME + DefaultAdvisorAutoProxyCreator.SEPARATOR));
assertThat(aapc.isUsePrefix()).isFalse();
}
/**
* If no pointcuts match (no attrs) there should be proxying.
*/
@Test
void testNoProxy() throws Exception {
BeanFactory bf = getBeanFactory();
Object o = bf.getBean("noSetters");
assertThat(AopUtils.isAopProxy(o)).isFalse();
}
@Test
void testTxIsProxied() throws Exception {
BeanFactory bf = getBeanFactory();
ITestBean test = (ITestBean) bf.getBean("test");
assertThat(AopUtils.isAopProxy(test)).isTrue();
}
@Test
void testRegexpApplied() throws Exception {
BeanFactory bf = getBeanFactory();
ITestBean test = (ITestBean) bf.getBean("test");
MethodCounter counter = (MethodCounter) bf.getBean("countingAdvice");
assertThat(counter.getCalls()).isEqualTo(0);
test.getName();
assertThat(counter.getCalls()).isEqualTo(1);
}
@Test
void testTransactionAttributeOnMethod() throws Exception {
BeanFactory bf = getBeanFactory();
ITestBean test = (ITestBean) bf.getBean("test");
CallCountingTransactionManager txMan = (CallCountingTransactionManager) bf.getBean(TXMANAGER_BEAN_NAME);
OrderedTxCheckAdvisor txc = (OrderedTxCheckAdvisor) bf.getBean("orderedBeforeTransaction");
assertThat(txc.getCountingBeforeAdvice().getCalls()).isEqualTo(0);
assertThat(txMan.commits).isEqualTo(0);
assertThat(test.getAge()).as("Initial value was correct").isEqualTo(4);
int newAge = 5;
test.setAge(newAge);
assertThat(txc.getCountingBeforeAdvice().getCalls()).isEqualTo(1);
assertThat(test.getAge()).as("New value set correctly").isEqualTo(newAge);
assertThat(txMan.commits).as("Transaction counts match").isEqualTo(1);
}
/**
* Should not roll back on servlet exception.
*/
@Test
void testRollbackRulesOnMethodCauseRollback() throws Exception {
BeanFactory bf = getBeanFactory();
Rollback rb = (Rollback) bf.getBean("rollback");
CallCountingTransactionManager txMan = (CallCountingTransactionManager) bf.getBean(TXMANAGER_BEAN_NAME);
OrderedTxCheckAdvisor txc = (OrderedTxCheckAdvisor) bf.getBean("orderedBeforeTransaction");
assertThat(txc.getCountingBeforeAdvice().getCalls()).isEqualTo(0);
assertThat(txMan.commits).isEqualTo(0);
rb.echoException(null);
// Fires only on setters
assertThat(txc.getCountingBeforeAdvice().getCalls()).isEqualTo(0);
assertThat(txMan.commits).as("Transaction counts match").isEqualTo(1);
assertThat(txMan.rollbacks).isEqualTo(0);
Exception ex = new Exception();
try {
rb.echoException(ex);
}
catch (Exception actual) {
assertThat(actual).isEqualTo(ex);
}
assertThat(txMan.rollbacks).as("Transaction counts match").isEqualTo(1);
}
@Test
void testRollbackRulesOnMethodPreventRollback() throws Exception {
BeanFactory bf = getBeanFactory();
Rollback rb = (Rollback) bf.getBean("rollback");
CallCountingTransactionManager txMan = (CallCountingTransactionManager) bf.getBean(TXMANAGER_BEAN_NAME);
assertThat(txMan.commits).isEqualTo(0);
// Should NOT roll back on ServletException
try {
rb.echoException(new ServletException());
}
catch (ServletException ex) {
}
assertThat(txMan.commits).as("Transaction counts match").isEqualTo(1);
}
@Test
void testProgrammaticRollback() throws Exception {
BeanFactory bf = getBeanFactory();
Object bean = bf.getBean(TXMANAGER_BEAN_NAME);
boolean condition = bean instanceof CallCountingTransactionManager;
assertThat(condition).isTrue();
CallCountingTransactionManager txMan = (CallCountingTransactionManager) bf.getBean(TXMANAGER_BEAN_NAME);
Rollback rb = (Rollback) bf.getBean("rollback");
assertThat(txMan.commits).isEqualTo(0);
rb.rollbackOnly(false);
assertThat(txMan.commits).as("Transaction counts match").isEqualTo(1);
assertThat(txMan.rollbacks).isEqualTo(0);
// Will cause rollback only
rb.rollbackOnly(true);
assertThat(txMan.rollbacks).isEqualTo(1);
}
}
@SuppressWarnings("serial")
class NeverMatchAdvisor extends StaticMethodMatcherPointcutAdvisor {
public NeverMatchAdvisor() {
super(new NopInterceptor());
}
/**
* This method is solely to allow us to create a mixture of dependencies in
* the bean definitions. The dependencies don't have any meaning, and don't
* <b>do</b> anything.
*/
public void setDependencies(List<?> l) {
}
/**
* @see org.springframework.aop.MethodMatcher#matches(java.lang.reflect.Method, java.lang.Class)
*/
@Override
public boolean matches(Method m, @Nullable Class<?> targetClass) {
return false;
}
}
class NoSetters {
public void A() {
}
public int getB() {
return -1;
}
}
@SuppressWarnings("serial")
class OrderedTxCheckAdvisor extends StaticMethodMatcherPointcutAdvisor implements InitializingBean {
/**
* Should we insist on the presence of a transaction attribute or refuse to accept one?
*/
private boolean requireTransactionContext = false;
public void setRequireTransactionContext(boolean requireTransactionContext) {
this.requireTransactionContext = requireTransactionContext;
}
public boolean isRequireTransactionContext() {
return requireTransactionContext;
}
public CountingBeforeAdvice getCountingBeforeAdvice() {
return (CountingBeforeAdvice) getAdvice();
}
@Override
public void afterPropertiesSet() throws Exception {
setAdvice(new TxCountingBeforeAdvice());
}
@Override
public boolean matches(Method method, @Nullable Class<?> targetClass) {
return method.getName().startsWith("setAge");
}
private class TxCountingBeforeAdvice extends CountingBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
// do transaction checks
if (requireTransactionContext) {
TransactionInterceptor.currentTransactionStatus();
}
else {
try {
TransactionInterceptor.currentTransactionStatus();
throw new RuntimeException("Shouldn't have a transaction");
}
catch (NoTransactionException ex) {
// this is Ok
}
}
super.before(method, args, target);
}
}
}
class Rollback {
/**
* Inherits transaction attribute.
* Illustrates programmatic rollback.
*/
public void rollbackOnly(boolean rollbackOnly) {
if (rollbackOnly) {
setRollbackOnly();
}
}
/**
* Extracted in a protected method to facilitate testing
*/
protected void setRollbackOnly() {
TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
}
/**
* @org.springframework.transaction.interceptor.RuleBasedTransaction ( timeout=-1 )
* @org.springframework.transaction.interceptor.RollbackRule ( "java.lang.Exception" )
* @org.springframework.transaction.interceptor.NoRollbackRule ( "ServletException" )
*/
public void echoException(Exception ex) throws Exception {
if (ex != null) {
throw ex;
}
}
}
@@ -1,231 +0,0 @@
/*
* Copyright 2002-2022 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
*
* https://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.aop.framework.autoproxy;
import java.util.ArrayList;
import java.util.List;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatException;
/**
* Integration tests for advice invocation order for advice configured via
* AspectJ auto-proxy support.
*
* @author Sam Brannen
* @since 5.2.7
* @see org.springframework.aop.config.AopNamespaceHandlerAdviceOrderIntegrationTests
*/
class AspectJAutoProxyAdviceOrderIntegrationTests {
/**
* {@link After @After} advice declared as first <em>after</em> method in source code.
*/
@Nested
@SpringJUnitConfig(AfterAdviceFirstConfig.class)
@DirtiesContext
class AfterAdviceFirstTests {
@Test
void afterAdviceIsInvokedLast(@Autowired Echo echo, @Autowired AfterAdviceFirstAspect aspect) throws Exception {
assertThat(aspect.invocations).isEmpty();
assertThat(echo.echo(42)).isEqualTo(42);
assertThat(aspect.invocations).containsExactly("around - start", "before", "after returning", "after", "around - end");
aspect.invocations.clear();
assertThatException().isThrownBy(() -> echo.echo(new Exception()));
assertThat(aspect.invocations).containsExactly("around - start", "before", "after throwing", "after", "around - end");
}
}
/**
* This test class uses {@link AfterAdviceLastAspect} which declares its
* {@link After @After} advice as the last <em>after advice type</em> method
* in its source code.
*
* <p>On Java versions prior to JDK 7, we would have expected the {@code @After}
* advice method to be invoked before {@code @AfterThrowing} and
* {@code @AfterReturning} advice methods due to the AspectJ precedence
* rules implemented in
* {@link org.springframework.aop.aspectj.autoproxy.AspectJPrecedenceComparator}.
*/
@Nested
@SpringJUnitConfig(AfterAdviceLastConfig.class)
@DirtiesContext
class AfterAdviceLastTests {
@Test
void afterAdviceIsInvokedLast(@Autowired Echo echo, @Autowired AfterAdviceLastAspect aspect) throws Exception {
assertThat(aspect.invocations).isEmpty();
assertThat(echo.echo(42)).isEqualTo(42);
assertThat(aspect.invocations).containsExactly("around - start", "before", "after returning", "after", "around - end");
aspect.invocations.clear();
assertThatException().isThrownBy(() -> echo.echo(new Exception()));
assertThat(aspect.invocations).containsExactly("around - start", "before", "after throwing", "after", "around - end");
}
}
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
static class AfterAdviceFirstConfig {
@Bean
AfterAdviceFirstAspect echoAspect() {
return new AfterAdviceFirstAspect();
}
@Bean
Echo echo() {
return new Echo();
}
}
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
static class AfterAdviceLastConfig {
@Bean
AfterAdviceLastAspect echoAspect() {
return new AfterAdviceLastAspect();
}
@Bean
Echo echo() {
return new Echo();
}
}
static class Echo {
Object echo(Object obj) throws Exception {
if (obj instanceof Exception) {
throw (Exception) obj;
}
return obj;
}
}
/**
* {@link After @After} advice declared as first <em>after</em> method in source code.
*/
@Aspect
static class AfterAdviceFirstAspect {
List<String> invocations = new ArrayList<>();
@Pointcut("execution(* echo(*))")
void echo() {
}
@After("echo()")
void after() {
invocations.add("after");
}
@AfterReturning("echo()")
void afterReturning() {
invocations.add("after returning");
}
@AfterThrowing("echo()")
void afterThrowing() {
invocations.add("after throwing");
}
@Before("echo()")
void before() {
invocations.add("before");
}
@Around("echo()")
Object around(ProceedingJoinPoint joinPoint) throws Throwable {
invocations.add("around - start");
try {
return joinPoint.proceed();
}
finally {
invocations.add("around - end");
}
}
}
/**
* {@link After @After} advice declared as last <em>after</em> method in source code.
*/
@Aspect
static class AfterAdviceLastAspect {
List<String> invocations = new ArrayList<>();
@Pointcut("execution(* echo(*))")
void echo() {
}
@Around("echo()")
Object around(ProceedingJoinPoint joinPoint) throws Throwable {
invocations.add("around - start");
try {
return joinPoint.proceed();
}
finally {
invocations.add("around - end");
}
}
@Before("echo()")
void before() {
invocations.add("before");
}
@AfterReturning("echo()")
void afterReturning() {
invocations.add("after returning");
}
@AfterThrowing("echo()")
void afterThrowing() {
invocations.add("after throwing");
}
@After("echo()")
void after() {
invocations.add("after");
}
}
}
@@ -1,44 +0,0 @@
/*
* Copyright 2002-2019 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
*
* https://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.xml;
import java.util.ArrayList;
import java.util.List;
public class Component {
private String name;
private List<Component> components = new ArrayList<>();
// mmm, there is no setter method for the 'components'
public void addComponent(Component component) {
this.components.add(component);
}
public List<Component> getComponents() {
return components;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@@ -1,63 +0,0 @@
/*
* Copyright 2002-2019 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
*
* https://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.xml;
import java.util.List;
import org.w3c.dom.Element;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.util.CollectionUtils;
import org.springframework.util.xml.DomUtils;
public class ComponentBeanDefinitionParser extends AbstractBeanDefinitionParser {
@Override
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
return parseComponentElement(element);
}
private static AbstractBeanDefinition parseComponentElement(Element element) {
BeanDefinitionBuilder factory = BeanDefinitionBuilder.rootBeanDefinition(ComponentFactoryBean.class);
factory.addPropertyValue("parent", parseComponent(element));
List<Element> childElements = DomUtils.getChildElementsByTagName(element, "component");
if (!CollectionUtils.isEmpty(childElements)) {
parseChildComponents(childElements, factory);
}
return factory.getBeanDefinition();
}
private static BeanDefinition parseComponent(Element element) {
BeanDefinitionBuilder component = BeanDefinitionBuilder.rootBeanDefinition(Component.class);
component.addPropertyValue("name", element.getAttribute("name"));
return component.getBeanDefinition();
}
private static void parseChildComponents(List<Element> childElements, BeanDefinitionBuilder factory) {
ManagedList<BeanDefinition> children = new ManagedList<>(childElements.size());
for (Element element : childElements) {
children.add(parseComponentElement(element));
}
factory.addPropertyValue("children", children);
}
}
@@ -1,81 +0,0 @@
/*
* Copyright 2002-2019 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
*
* https://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.xml;
import java.util.List;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.core.io.ClassPathResource;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Costin Leau
*/
@TestInstance(Lifecycle.PER_CLASS)
class ComponentBeanDefinitionParserTests {
private final DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
@BeforeAll
void setUp() throws Exception {
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
new ClassPathResource("component-config.xml", ComponentBeanDefinitionParserTests.class));
}
@AfterAll
void tearDown() {
bf.destroySingletons();
}
@Test
void testBionicBasic() {
Component cp = getBionicFamily();
assertThat("Bionic-1").isEqualTo(cp.getName());
}
@Test
void testBionicFirstLevelChildren() {
Component cp = getBionicFamily();
List<Component> components = cp.getComponents();
assertThat(2).isEqualTo(components.size());
assertThat("Mother-1").isEqualTo(components.get(0).getName());
assertThat("Rock-1").isEqualTo(components.get(1).getName());
}
@Test
void testBionicSecondLevelChildren() {
Component cp = getBionicFamily();
List<Component> components = cp.getComponents().get(0).getComponents();
assertThat(2).isEqualTo(components.size());
assertThat("Karate-1").isEqualTo(components.get(0).getName());
assertThat("Sport-1").isEqualTo(components.get(1).getName());
}
private Component getBionicFamily() {
return bf.getBean("bionic-family", Component.class);
}
}
@@ -1,25 +0,0 @@
/*
* Copyright 2002-2019 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
*
* https://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.xml;
public class ComponentNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
registerBeanDefinitionParser("component", new ComponentBeanDefinitionParser());
}
}
@@ -1,135 +0,0 @@
/*
* Copyright 2002-2022 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
*
* https://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.cache.annotation;
import java.util.Collections;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.aop.Advisor;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.support.AopUtils;
import org.springframework.cache.CacheManager;
import org.springframework.cache.interceptor.BeanFactoryCacheOperationSourceAdvisor;
import org.springframework.cache.support.NoOpCacheManager;
import org.springframework.context.annotation.AdviceMode;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Repository;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatException;
/**
* Integration tests for the @EnableCaching annotation.
*
* @author Chris Beams
* @since 3.1
*/
@SuppressWarnings("resource")
class EnableCachingIntegrationTests {
@Test
void repositoryIsClassBasedCacheProxy() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(Config.class, ProxyTargetClassCachingConfig.class);
ctx.refresh();
assertCacheProxying(ctx);
assertThat(AopUtils.isCglibProxy(ctx.getBean(FooRepository.class))).isTrue();
}
@Test
void repositoryUsesAspectJAdviceMode() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(Config.class, AspectJCacheConfig.class);
// this test is a bit fragile, but gets the job done, proving that an
// attempt was made to look up the AJ aspect. It's due to classpath issues
// in .integration-tests that it's not found.
assertThatException().isThrownBy(ctx::refresh)
.withMessageContaining("AspectJCachingConfiguration");
}
private void assertCacheProxying(AnnotationConfigApplicationContext ctx) {
FooRepository repo = ctx.getBean(FooRepository.class);
assertThat(isCacheProxy(repo)).isTrue();
}
private boolean isCacheProxy(FooRepository repo) {
if (AopUtils.isAopProxy(repo)) {
for (Advisor advisor : ((Advised)repo).getAdvisors()) {
if (advisor instanceof BeanFactoryCacheOperationSourceAdvisor) {
return true;
}
}
}
return false;
}
@Configuration
@EnableCaching(proxyTargetClass=true)
static class ProxyTargetClassCachingConfig {
@Bean
CacheManager mgr() {
return new NoOpCacheManager();
}
}
@Configuration
static class Config {
@Bean
FooRepository fooRepository() {
return new DummyFooRepository();
}
}
@Configuration
@EnableCaching(mode=AdviceMode.ASPECTJ)
static class AspectJCacheConfig {
@Bean
CacheManager cacheManager() {
return new NoOpCacheManager();
}
}
interface FooRepository {
List<Object> findAll();
}
@Repository
static class DummyFooRepository implements FooRepository {
@Override
@Cacheable("primary")
public List<Object> findAll() {
return Collections.emptyList();
}
}
}
@@ -1,401 +0,0 @@
/*
* Copyright 2002-2022 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
*
* https://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.context.annotation.jsr330;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Named;
import javax.inject.Singleton;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.ScopeMetadata;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.support.GenericWebApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Mark Fisher
* @author Juergen Hoeller
* @author Chris Beams
*/
class ClassPathBeanDefinitionScannerJsr330ScopeIntegrationTests {
private static final String DEFAULT_NAME = "default";
private static final String MODIFIED_NAME = "modified";
private ServletRequestAttributes oldRequestAttributes;
private ServletRequestAttributes newRequestAttributes;
private ServletRequestAttributes oldRequestAttributesWithSession;
private ServletRequestAttributes newRequestAttributesWithSession;
@BeforeEach
void setup() {
this.oldRequestAttributes = new ServletRequestAttributes(new MockHttpServletRequest());
this.newRequestAttributes = new ServletRequestAttributes(new MockHttpServletRequest());
MockHttpServletRequest oldRequestWithSession = new MockHttpServletRequest();
oldRequestWithSession.setSession(new MockHttpSession());
this.oldRequestAttributesWithSession = new ServletRequestAttributes(oldRequestWithSession);
MockHttpServletRequest newRequestWithSession = new MockHttpServletRequest();
newRequestWithSession.setSession(new MockHttpSession());
this.newRequestAttributesWithSession = new ServletRequestAttributes(newRequestWithSession);
}
@AfterEach
void reset() {
RequestContextHolder.setRequestAttributes(null);
}
@Test
void testPrototype() {
ApplicationContext context = createContext(ScopedProxyMode.NO);
ScopedTestBean bean = (ScopedTestBean) context.getBean("prototype");
assertThat(bean).isNotNull();
assertThat(context.isPrototype("prototype")).isTrue();
assertThat(context.isSingleton("prototype")).isFalse();
}
@Test
void testSingletonScopeWithNoProxy() {
RequestContextHolder.setRequestAttributes(oldRequestAttributes);
ApplicationContext context = createContext(ScopedProxyMode.NO);
ScopedTestBean bean = (ScopedTestBean) context.getBean("singleton");
assertThat(context.isSingleton("singleton")).isTrue();
assertThat(context.isPrototype("singleton")).isFalse();
// should not be a proxy
assertThat(AopUtils.isAopProxy(bean)).isFalse();
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
bean.setName(MODIFIED_NAME);
RequestContextHolder.setRequestAttributes(newRequestAttributes);
// not a proxy so this should not have changed
assertThat(bean.getName()).isEqualTo(MODIFIED_NAME);
// singleton bean, so name should be modified even after lookup
ScopedTestBean bean2 = (ScopedTestBean) context.getBean("singleton");
assertThat(bean2.getName()).isEqualTo(MODIFIED_NAME);
}
@Test
void testSingletonScopeIgnoresProxyInterfaces() {
RequestContextHolder.setRequestAttributes(oldRequestAttributes);
ApplicationContext context = createContext(ScopedProxyMode.INTERFACES);
ScopedTestBean bean = (ScopedTestBean) context.getBean("singleton");
// should not be a proxy
assertThat(AopUtils.isAopProxy(bean)).isFalse();
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
bean.setName(MODIFIED_NAME);
RequestContextHolder.setRequestAttributes(newRequestAttributes);
// not a proxy so this should not have changed
assertThat(bean.getName()).isEqualTo(MODIFIED_NAME);
// singleton bean, so name should be modified even after lookup
ScopedTestBean bean2 = (ScopedTestBean) context.getBean("singleton");
assertThat(bean2.getName()).isEqualTo(MODIFIED_NAME);
}
@Test
void testSingletonScopeIgnoresProxyTargetClass() {
RequestContextHolder.setRequestAttributes(oldRequestAttributes);
ApplicationContext context = createContext(ScopedProxyMode.TARGET_CLASS);
ScopedTestBean bean = (ScopedTestBean) context.getBean("singleton");
// should not be a proxy
assertThat(AopUtils.isAopProxy(bean)).isFalse();
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
bean.setName(MODIFIED_NAME);
RequestContextHolder.setRequestAttributes(newRequestAttributes);
// not a proxy so this should not have changed
assertThat(bean.getName()).isEqualTo(MODIFIED_NAME);
// singleton bean, so name should be modified even after lookup
ScopedTestBean bean2 = (ScopedTestBean) context.getBean("singleton");
assertThat(bean2.getName()).isEqualTo(MODIFIED_NAME);
}
@Test
void testRequestScopeWithNoProxy() {
RequestContextHolder.setRequestAttributes(oldRequestAttributes);
ApplicationContext context = createContext(ScopedProxyMode.NO);
ScopedTestBean bean = (ScopedTestBean) context.getBean("request");
// should not be a proxy
assertThat(AopUtils.isAopProxy(bean)).isFalse();
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
bean.setName(MODIFIED_NAME);
RequestContextHolder.setRequestAttributes(newRequestAttributes);
// not a proxy so this should not have changed
assertThat(bean.getName()).isEqualTo(MODIFIED_NAME);
// but a newly retrieved bean should have the default name
ScopedTestBean bean2 = (ScopedTestBean) context.getBean("request");
assertThat(bean2.getName()).isEqualTo(DEFAULT_NAME);
}
@Test
void testRequestScopeWithProxiedInterfaces() {
RequestContextHolder.setRequestAttributes(oldRequestAttributes);
ApplicationContext context = createContext(ScopedProxyMode.INTERFACES);
IScopedTestBean bean = (IScopedTestBean) context.getBean("request");
// should be dynamic proxy, implementing both interfaces
assertThat(AopUtils.isJdkDynamicProxy(bean)).isTrue();
boolean condition = bean instanceof AnotherScopeTestInterface;
assertThat(condition).isTrue();
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
bean.setName(MODIFIED_NAME);
RequestContextHolder.setRequestAttributes(newRequestAttributes);
// this is a proxy so it should be reset to default
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
RequestContextHolder.setRequestAttributes(oldRequestAttributes);
assertThat(bean.getName()).isEqualTo(MODIFIED_NAME);
}
@Test
void testRequestScopeWithProxiedTargetClass() {
RequestContextHolder.setRequestAttributes(oldRequestAttributes);
ApplicationContext context = createContext(ScopedProxyMode.TARGET_CLASS);
IScopedTestBean bean = (IScopedTestBean) context.getBean("request");
// should be a class-based proxy
assertThat(AopUtils.isCglibProxy(bean)).isTrue();
boolean condition = bean instanceof RequestScopedTestBean;
assertThat(condition).isTrue();
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
bean.setName(MODIFIED_NAME);
RequestContextHolder.setRequestAttributes(newRequestAttributes);
// this is a proxy so it should be reset to default
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
RequestContextHolder.setRequestAttributes(oldRequestAttributes);
assertThat(bean.getName()).isEqualTo(MODIFIED_NAME);
}
@Test
void testSessionScopeWithNoProxy() {
RequestContextHolder.setRequestAttributes(oldRequestAttributesWithSession);
ApplicationContext context = createContext(ScopedProxyMode.NO);
ScopedTestBean bean = (ScopedTestBean) context.getBean("session");
// should not be a proxy
assertThat(AopUtils.isAopProxy(bean)).isFalse();
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
bean.setName(MODIFIED_NAME);
RequestContextHolder.setRequestAttributes(newRequestAttributesWithSession);
// not a proxy so this should not have changed
assertThat(bean.getName()).isEqualTo(MODIFIED_NAME);
// but a newly retrieved bean should have the default name
ScopedTestBean bean2 = (ScopedTestBean) context.getBean("session");
assertThat(bean2.getName()).isEqualTo(DEFAULT_NAME);
}
@Test
void testSessionScopeWithProxiedInterfaces() {
RequestContextHolder.setRequestAttributes(oldRequestAttributesWithSession);
ApplicationContext context = createContext(ScopedProxyMode.INTERFACES);
IScopedTestBean bean = (IScopedTestBean) context.getBean("session");
// should be dynamic proxy, implementing both interfaces
assertThat(AopUtils.isJdkDynamicProxy(bean)).isTrue();
boolean condition = bean instanceof AnotherScopeTestInterface;
assertThat(condition).isTrue();
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
bean.setName(MODIFIED_NAME);
RequestContextHolder.setRequestAttributes(newRequestAttributesWithSession);
// this is a proxy so it should be reset to default
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
bean.setName(MODIFIED_NAME);
IScopedTestBean bean2 = (IScopedTestBean) context.getBean("session");
assertThat(bean2.getName()).isEqualTo(MODIFIED_NAME);
bean2.setName(DEFAULT_NAME);
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
RequestContextHolder.setRequestAttributes(oldRequestAttributesWithSession);
assertThat(bean.getName()).isEqualTo(MODIFIED_NAME);
}
@Test
void testSessionScopeWithProxiedTargetClass() {
RequestContextHolder.setRequestAttributes(oldRequestAttributesWithSession);
ApplicationContext context = createContext(ScopedProxyMode.TARGET_CLASS);
IScopedTestBean bean = (IScopedTestBean) context.getBean("session");
// should be a class-based proxy
assertThat(AopUtils.isCglibProxy(bean)).isTrue();
boolean condition1 = bean instanceof ScopedTestBean;
assertThat(condition1).isTrue();
boolean condition = bean instanceof SessionScopedTestBean;
assertThat(condition).isTrue();
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
bean.setName(MODIFIED_NAME);
RequestContextHolder.setRequestAttributes(newRequestAttributesWithSession);
// this is a proxy so it should be reset to default
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
bean.setName(MODIFIED_NAME);
IScopedTestBean bean2 = (IScopedTestBean) context.getBean("session");
assertThat(bean2.getName()).isEqualTo(MODIFIED_NAME);
bean2.setName(DEFAULT_NAME);
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
RequestContextHolder.setRequestAttributes(oldRequestAttributesWithSession);
assertThat(bean.getName()).isEqualTo(MODIFIED_NAME);
}
private ApplicationContext createContext(final ScopedProxyMode scopedProxyMode) {
GenericWebApplicationContext context = new GenericWebApplicationContext();
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.setIncludeAnnotationConfig(false);
scanner.setScopeMetadataResolver(definition -> {
ScopeMetadata metadata = new ScopeMetadata();
if (definition instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
for (String type : annDef.getMetadata().getAnnotationTypes()) {
if (type.equals(javax.inject.Singleton.class.getName())) {
metadata.setScopeName(BeanDefinition.SCOPE_SINGLETON);
break;
}
else if (annDef.getMetadata().getMetaAnnotationTypes(type).contains(javax.inject.Scope.class.getName())) {
metadata.setScopeName(type.substring(type.length() - 13, type.length() - 6).toLowerCase());
metadata.setScopedProxyMode(scopedProxyMode);
break;
}
else if (type.startsWith("javax.inject")) {
metadata.setScopeName(BeanDefinition.SCOPE_PROTOTYPE);
}
}
}
return metadata;
});
// Scan twice in order to find errors in the bean definition compatibility check.
scanner.scan(getClass().getPackage().getName());
scanner.scan(getClass().getPackage().getName());
context.registerAlias("classPathBeanDefinitionScannerJsr330ScopeIntegrationTests.SessionScopedTestBean", "session");
context.refresh();
return context;
}
public interface IScopedTestBean {
String getName();
void setName(String name);
}
public static abstract class ScopedTestBean implements IScopedTestBean {
private String name = DEFAULT_NAME;
@Override
public String getName() { return this.name; }
@Override
public void setName(String name) { this.name = name; }
}
@Named("prototype")
public static class PrototypeScopedTestBean extends ScopedTestBean {
}
@Named("singleton")
@Singleton
public static class SingletonScopedTestBean extends ScopedTestBean {
}
public interface AnotherScopeTestInterface {
}
@Named("request")
@RequestScoped
public static class RequestScopedTestBean extends ScopedTestBean implements AnotherScopeTestInterface {
}
@Named
@SessionScoped
public static class SessionScopedTestBean extends ScopedTestBean implements AnotherScopeTestInterface {
}
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@javax.inject.Scope
public @interface RequestScoped {
}
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@javax.inject.Scope
public @interface SessionScoped {
}
}
@@ -1,341 +0,0 @@
/*
* Copyright 2002-2019 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
*
* https://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.context.annotation.scope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.aop.support.AopUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.stereotype.Component;
import org.springframework.web.context.annotation.RequestScope;
import org.springframework.web.context.annotation.SessionScope;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.support.GenericWebApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.context.annotation.ScopedProxyMode.DEFAULT;
import static org.springframework.context.annotation.ScopedProxyMode.INTERFACES;
import static org.springframework.context.annotation.ScopedProxyMode.NO;
import static org.springframework.context.annotation.ScopedProxyMode.TARGET_CLASS;
/**
* @author Mark Fisher
* @author Juergen Hoeller
* @author Chris Beams
* @author Sam Brannen
*/
class ClassPathBeanDefinitionScannerScopeIntegrationTests {
private static final String DEFAULT_NAME = "default";
private static final String MODIFIED_NAME = "modified";
private ServletRequestAttributes oldRequestAttributes = new ServletRequestAttributes(new MockHttpServletRequest());
private ServletRequestAttributes newRequestAttributes = new ServletRequestAttributes(new MockHttpServletRequest());
private ServletRequestAttributes oldRequestAttributesWithSession;
private ServletRequestAttributes newRequestAttributesWithSession;
@BeforeEach
void setup() {
MockHttpServletRequest oldRequestWithSession = new MockHttpServletRequest();
oldRequestWithSession.setSession(new MockHttpSession());
this.oldRequestAttributesWithSession = new ServletRequestAttributes(oldRequestWithSession);
MockHttpServletRequest newRequestWithSession = new MockHttpServletRequest();
newRequestWithSession.setSession(new MockHttpSession());
this.newRequestAttributesWithSession = new ServletRequestAttributes(newRequestWithSession);
}
@AfterEach
void reset() {
RequestContextHolder.resetRequestAttributes();
}
@Test
void singletonScopeWithNoProxy() {
RequestContextHolder.setRequestAttributes(oldRequestAttributes);
ApplicationContext context = createContext(NO);
ScopedTestBean bean = (ScopedTestBean) context.getBean("singleton");
// should not be a proxy
assertThat(AopUtils.isAopProxy(bean)).isFalse();
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
bean.setName(MODIFIED_NAME);
RequestContextHolder.setRequestAttributes(newRequestAttributes);
// not a proxy so this should not have changed
assertThat(bean.getName()).isEqualTo(MODIFIED_NAME);
// singleton bean, so name should be modified even after lookup
ScopedTestBean bean2 = (ScopedTestBean) context.getBean("singleton");
assertThat(bean2.getName()).isEqualTo(MODIFIED_NAME);
}
@Test
void singletonScopeIgnoresProxyInterfaces() {
RequestContextHolder.setRequestAttributes(oldRequestAttributes);
ApplicationContext context = createContext(INTERFACES);
ScopedTestBean bean = (ScopedTestBean) context.getBean("singleton");
// should not be a proxy
assertThat(AopUtils.isAopProxy(bean)).isFalse();
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
bean.setName(MODIFIED_NAME);
RequestContextHolder.setRequestAttributes(newRequestAttributes);
// not a proxy so this should not have changed
assertThat(bean.getName()).isEqualTo(MODIFIED_NAME);
// singleton bean, so name should be modified even after lookup
ScopedTestBean bean2 = (ScopedTestBean) context.getBean("singleton");
assertThat(bean2.getName()).isEqualTo(MODIFIED_NAME);
}
@Test
void singletonScopeIgnoresProxyTargetClass() {
RequestContextHolder.setRequestAttributes(oldRequestAttributes);
ApplicationContext context = createContext(TARGET_CLASS);
ScopedTestBean bean = (ScopedTestBean) context.getBean("singleton");
// should not be a proxy
assertThat(AopUtils.isAopProxy(bean)).isFalse();
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
bean.setName(MODIFIED_NAME);
RequestContextHolder.setRequestAttributes(newRequestAttributes);
// not a proxy so this should not have changed
assertThat(bean.getName()).isEqualTo(MODIFIED_NAME);
// singleton bean, so name should be modified even after lookup
ScopedTestBean bean2 = (ScopedTestBean) context.getBean("singleton");
assertThat(bean2.getName()).isEqualTo(MODIFIED_NAME);
}
@Test
void requestScopeWithNoProxy() {
RequestContextHolder.setRequestAttributes(oldRequestAttributes);
ApplicationContext context = createContext(NO);
ScopedTestBean bean = (ScopedTestBean) context.getBean("request");
// should not be a proxy
assertThat(AopUtils.isAopProxy(bean)).isFalse();
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
bean.setName(MODIFIED_NAME);
RequestContextHolder.setRequestAttributes(newRequestAttributes);
// not a proxy so this should not have changed
assertThat(bean.getName()).isEqualTo(MODIFIED_NAME);
// but a newly retrieved bean should have the default name
ScopedTestBean bean2 = (ScopedTestBean) context.getBean("request");
assertThat(bean2.getName()).isEqualTo(DEFAULT_NAME);
}
@Test
void requestScopeWithProxiedInterfaces() {
RequestContextHolder.setRequestAttributes(oldRequestAttributes);
ApplicationContext context = createContext(INTERFACES);
IScopedTestBean bean = (IScopedTestBean) context.getBean("request");
// should be dynamic proxy, implementing both interfaces
assertThat(AopUtils.isJdkDynamicProxy(bean)).isTrue();
boolean condition = bean instanceof AnotherScopeTestInterface;
assertThat(condition).isTrue();
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
bean.setName(MODIFIED_NAME);
RequestContextHolder.setRequestAttributes(newRequestAttributes);
// this is a proxy so it should be reset to default
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
RequestContextHolder.setRequestAttributes(oldRequestAttributes);
assertThat(bean.getName()).isEqualTo(MODIFIED_NAME);
}
@Test
void requestScopeWithProxiedTargetClass() {
RequestContextHolder.setRequestAttributes(oldRequestAttributes);
ApplicationContext context = createContext(TARGET_CLASS);
IScopedTestBean bean = (IScopedTestBean) context.getBean("request");
// should be a class-based proxy
assertThat(AopUtils.isCglibProxy(bean)).isTrue();
boolean condition = bean instanceof RequestScopedTestBean;
assertThat(condition).isTrue();
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
bean.setName(MODIFIED_NAME);
RequestContextHolder.setRequestAttributes(newRequestAttributes);
// this is a proxy so it should be reset to default
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
RequestContextHolder.setRequestAttributes(oldRequestAttributes);
assertThat(bean.getName()).isEqualTo(MODIFIED_NAME);
}
@Test
void sessionScopeWithNoProxy() {
RequestContextHolder.setRequestAttributes(oldRequestAttributesWithSession);
ApplicationContext context = createContext(NO);
ScopedTestBean bean = (ScopedTestBean) context.getBean("session");
// should not be a proxy
assertThat(AopUtils.isAopProxy(bean)).isFalse();
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
bean.setName(MODIFIED_NAME);
RequestContextHolder.setRequestAttributes(newRequestAttributesWithSession);
// not a proxy so this should not have changed
assertThat(bean.getName()).isEqualTo(MODIFIED_NAME);
// but a newly retrieved bean should have the default name
ScopedTestBean bean2 = (ScopedTestBean) context.getBean("session");
assertThat(bean2.getName()).isEqualTo(DEFAULT_NAME);
}
@Test
void sessionScopeWithProxiedInterfaces() {
RequestContextHolder.setRequestAttributes(oldRequestAttributesWithSession);
ApplicationContext context = createContext(INTERFACES);
IScopedTestBean bean = (IScopedTestBean) context.getBean("session");
// should be dynamic proxy, implementing both interfaces
assertThat(AopUtils.isJdkDynamicProxy(bean)).isTrue();
boolean condition = bean instanceof AnotherScopeTestInterface;
assertThat(condition).isTrue();
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
bean.setName(MODIFIED_NAME);
RequestContextHolder.setRequestAttributes(newRequestAttributesWithSession);
// this is a proxy so it should be reset to default
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
bean.setName(MODIFIED_NAME);
IScopedTestBean bean2 = (IScopedTestBean) context.getBean("session");
assertThat(bean2.getName()).isEqualTo(MODIFIED_NAME);
bean2.setName(DEFAULT_NAME);
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
RequestContextHolder.setRequestAttributes(oldRequestAttributesWithSession);
assertThat(bean.getName()).isEqualTo(MODIFIED_NAME);
}
@Test
void sessionScopeWithProxiedTargetClass() {
RequestContextHolder.setRequestAttributes(oldRequestAttributesWithSession);
ApplicationContext context = createContext(TARGET_CLASS);
IScopedTestBean bean = (IScopedTestBean) context.getBean("session");
// should be a class-based proxy
assertThat(AopUtils.isCglibProxy(bean)).isTrue();
boolean condition1 = bean instanceof ScopedTestBean;
assertThat(condition1).isTrue();
boolean condition = bean instanceof SessionScopedTestBean;
assertThat(condition).isTrue();
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
bean.setName(MODIFIED_NAME);
RequestContextHolder.setRequestAttributes(newRequestAttributesWithSession);
// this is a proxy so it should be reset to default
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
bean.setName(MODIFIED_NAME);
IScopedTestBean bean2 = (IScopedTestBean) context.getBean("session");
assertThat(bean2.getName()).isEqualTo(MODIFIED_NAME);
bean2.setName(DEFAULT_NAME);
assertThat(bean.getName()).isEqualTo(DEFAULT_NAME);
RequestContextHolder.setRequestAttributes(oldRequestAttributesWithSession);
assertThat(bean.getName()).isEqualTo(MODIFIED_NAME);
}
private ApplicationContext createContext(ScopedProxyMode scopedProxyMode) {
GenericWebApplicationContext context = new GenericWebApplicationContext();
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.setIncludeAnnotationConfig(false);
scanner.setBeanNameGenerator((definition, registry) -> definition.getScope());
scanner.setScopedProxyMode(scopedProxyMode);
// Scan twice in order to find errors in the bean definition compatibility check.
scanner.scan(getClass().getPackage().getName());
scanner.scan(getClass().getPackage().getName());
context.refresh();
return context;
}
interface IScopedTestBean {
String getName();
void setName(String name);
}
static abstract class ScopedTestBean implements IScopedTestBean {
private String name = DEFAULT_NAME;
@Override
public String getName() { return this.name; }
@Override
public void setName(String name) { this.name = name; }
}
@Component
static class SingletonScopedTestBean extends ScopedTestBean {
}
interface AnotherScopeTestInterface {
}
@Component
@RequestScope(proxyMode = DEFAULT)
static class RequestScopedTestBean extends ScopedTestBean implements AnotherScopeTestInterface {
}
@Component
@SessionScope(proxyMode = DEFAULT)
static class SessionScopedTestBean extends ScopedTestBean implements AnotherScopeTestInterface {
}
}
@@ -1,710 +0,0 @@
/*
* Copyright 2002-2019 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
*
* https://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.core.env;
import java.io.File;
import java.io.IOException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Profile;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jca.context.ResourceAdapterApplicationContext;
import org.springframework.jca.support.SimpleBootstrapContext;
import org.springframework.jca.work.SimpleTaskWorkManager;
import org.springframework.mock.env.MockEnvironment;
import org.springframework.mock.env.MockPropertySource;
import org.springframework.mock.web.MockServletConfig;
import org.springframework.mock.web.MockServletContext;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AbstractRefreshableWebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.context.support.StandardServletEnvironment;
import org.springframework.web.context.support.StaticWebApplicationContext;
import org.springframework.web.context.support.XmlWebApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition;
import static org.springframework.context.ConfigurableApplicationContext.ENVIRONMENT_BEAN_NAME;
import static org.springframework.core.env.EnvironmentSystemIntegrationTests.Constants.DERIVED_DEV_BEAN_NAME;
import static org.springframework.core.env.EnvironmentSystemIntegrationTests.Constants.DERIVED_DEV_ENV_NAME;
import static org.springframework.core.env.EnvironmentSystemIntegrationTests.Constants.DEV_BEAN_NAME;
import static org.springframework.core.env.EnvironmentSystemIntegrationTests.Constants.DEV_ENV_NAME;
import static org.springframework.core.env.EnvironmentSystemIntegrationTests.Constants.ENVIRONMENT_AWARE_BEAN_NAME;
import static org.springframework.core.env.EnvironmentSystemIntegrationTests.Constants.PROD_BEAN_NAME;
import static org.springframework.core.env.EnvironmentSystemIntegrationTests.Constants.PROD_ENV_NAME;
import static org.springframework.core.env.EnvironmentSystemIntegrationTests.Constants.TRANSITIVE_BEAN_NAME;
import static org.springframework.core.env.EnvironmentSystemIntegrationTests.Constants.XML_PATH;
/**
* System integration tests for container support of the {@link Environment} API.
*
* <p>
* Tests all existing BeanFactory and ApplicationContext implementations to ensure that:
* <ul>
* <li>a standard environment object is always present
* <li>a custom environment object can be set and retrieved against the factory/context
* <li>the {@link EnvironmentAware} interface is respected
* <li>the environment object is registered with the container as a singleton bean (if an
* ApplicationContext)
* <li>bean definition files (if any, and whether XML or @Configuration) are registered
* conditionally based on environment metadata
* </ul>
*
* @author Chris Beams
* @author Sam Brannen
* @see org.springframework.context.support.EnvironmentIntegrationTests
*/
@SuppressWarnings("resource")
public class EnvironmentSystemIntegrationTests {
private final ConfigurableEnvironment prodEnv = new StandardEnvironment();
private final ConfigurableEnvironment devEnv = new StandardEnvironment();
private final ConfigurableEnvironment prodWebEnv = new StandardServletEnvironment();
@BeforeEach
void setUp() {
prodEnv.setActiveProfiles(PROD_ENV_NAME);
devEnv.setActiveProfiles(DEV_ENV_NAME);
prodWebEnv.setActiveProfiles(PROD_ENV_NAME);
}
@Test
void genericApplicationContext_standardEnv() {
ConfigurableApplicationContext ctx = new GenericApplicationContext(newBeanFactoryWithEnvironmentAwareBean());
ctx.refresh();
assertHasStandardEnvironment(ctx);
assertEnvironmentBeanRegistered(ctx);
assertEnvironmentAwareInvoked(ctx, ctx.getEnvironment());
}
@Test
void genericApplicationContext_customEnv() {
GenericApplicationContext ctx = new GenericApplicationContext(newBeanFactoryWithEnvironmentAwareBean());
ctx.setEnvironment(prodEnv);
ctx.refresh();
assertHasEnvironment(ctx, prodEnv);
assertEnvironmentBeanRegistered(ctx);
assertEnvironmentAwareInvoked(ctx, prodEnv);
}
@Test
void xmlBeanDefinitionReader_inheritsEnvironmentFromEnvironmentCapableBDR() {
GenericApplicationContext ctx = new GenericApplicationContext();
ctx.setEnvironment(prodEnv);
new XmlBeanDefinitionReader(ctx).loadBeanDefinitions(XML_PATH);
ctx.refresh();
assertThat(ctx.containsBean(DEV_BEAN_NAME)).isFalse();
assertThat(ctx.containsBean(PROD_BEAN_NAME)).isTrue();
}
@Test
void annotatedBeanDefinitionReader_inheritsEnvironmentFromEnvironmentCapableBDR() {
GenericApplicationContext ctx = new GenericApplicationContext();
ctx.setEnvironment(prodEnv);
new AnnotatedBeanDefinitionReader(ctx).register(Config.class);
ctx.refresh();
assertThat(ctx.containsBean(DEV_BEAN_NAME)).isFalse();
assertThat(ctx.containsBean(PROD_BEAN_NAME)).isTrue();
}
@Test
void classPathBeanDefinitionScanner_inheritsEnvironmentFromEnvironmentCapableBDR_scanProfileAnnotatedConfigClasses() {
// it's actually ConfigurationClassPostProcessor's Environment that gets the job done here.
GenericApplicationContext ctx = new GenericApplicationContext();
ctx.setEnvironment(prodEnv);
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(ctx);
scanner.scan("org.springframework.core.env.scan1");
ctx.refresh();
assertThat(ctx.containsBean(DEV_BEAN_NAME)).isFalse();
assertThat(ctx.containsBean(PROD_BEAN_NAME)).isTrue();
}
@Test
void classPathBeanDefinitionScanner_inheritsEnvironmentFromEnvironmentCapableBDR_scanProfileAnnotatedComponents() {
GenericApplicationContext ctx = new GenericApplicationContext();
ctx.setEnvironment(prodEnv);
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(ctx);
scanner.scan("org.springframework.core.env.scan2");
ctx.refresh();
assertThat(scanner.getEnvironment()).isEqualTo(ctx.getEnvironment());
assertThat(ctx.containsBean(DEV_BEAN_NAME)).isFalse();
assertThat(ctx.containsBean(PROD_BEAN_NAME)).isTrue();
}
@Test
void genericXmlApplicationContext() {
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
assertHasStandardEnvironment(ctx);
ctx.setEnvironment(prodEnv);
ctx.load(XML_PATH);
ctx.refresh();
assertHasEnvironment(ctx, prodEnv);
assertEnvironmentBeanRegistered(ctx);
assertEnvironmentAwareInvoked(ctx, prodEnv);
assertThat(ctx.containsBean(DEV_BEAN_NAME)).isFalse();
assertThat(ctx.containsBean(PROD_BEAN_NAME)).isTrue();
}
@Test
void classPathXmlApplicationContext() {
ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext(XML_PATH);
ctx.setEnvironment(prodEnv);
ctx.refresh();
assertEnvironmentBeanRegistered(ctx);
assertHasEnvironment(ctx, prodEnv);
assertEnvironmentAwareInvoked(ctx, ctx.getEnvironment());
assertThat(ctx.containsBean(DEV_BEAN_NAME)).isFalse();
assertThat(ctx.containsBean(PROD_BEAN_NAME)).isTrue();
}
@Test
void fileSystemXmlApplicationContext() throws IOException {
ClassPathResource xml = new ClassPathResource(XML_PATH);
File tmpFile = File.createTempFile("test", "xml");
FileCopyUtils.copy(xml.getFile(), tmpFile);
// strange - FSXAC strips leading '/' unless prefixed with 'file:'
ConfigurableApplicationContext ctx =
new FileSystemXmlApplicationContext(new String[] {"file:" + tmpFile.getPath()}, false);
ctx.setEnvironment(prodEnv);
ctx.refresh();
assertEnvironmentBeanRegistered(ctx);
assertHasEnvironment(ctx, prodEnv);
assertEnvironmentAwareInvoked(ctx, ctx.getEnvironment());
assertThat(ctx.containsBean(DEV_BEAN_NAME)).isFalse();
assertThat(ctx.containsBean(PROD_BEAN_NAME)).isTrue();
}
@Test
void annotationConfigApplicationContext_withPojos() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
assertHasStandardEnvironment(ctx);
ctx.setEnvironment(prodEnv);
ctx.register(EnvironmentAwareBean.class);
ctx.refresh();
assertEnvironmentAwareInvoked(ctx, prodEnv);
}
@Test
void annotationConfigApplicationContext_withProdEnvAndProdConfigClass() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
assertHasStandardEnvironment(ctx);
ctx.setEnvironment(prodEnv);
ctx.register(ProdConfig.class);
ctx.refresh();
assertThat(ctx.containsBean(PROD_BEAN_NAME)).isTrue();
}
@Test
void annotationConfigApplicationContext_withProdEnvAndDevConfigClass() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
assertHasStandardEnvironment(ctx);
ctx.setEnvironment(prodEnv);
ctx.register(DevConfig.class);
ctx.refresh();
assertThat(ctx.containsBean(DEV_BEAN_NAME)).isFalse();
assertThat(ctx.containsBean(TRANSITIVE_BEAN_NAME)).isFalse();
}
@Test
void annotationConfigApplicationContext_withDevEnvAndDevConfigClass() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
assertHasStandardEnvironment(ctx);
ctx.setEnvironment(devEnv);
ctx.register(DevConfig.class);
ctx.refresh();
assertThat(ctx.containsBean(DEV_BEAN_NAME)).isTrue();
assertThat(ctx.containsBean(TRANSITIVE_BEAN_NAME)).isTrue();
}
@Test
void annotationConfigApplicationContext_withImportedConfigClasses() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
assertHasStandardEnvironment(ctx);
ctx.setEnvironment(prodEnv);
ctx.register(Config.class);
ctx.refresh();
assertEnvironmentAwareInvoked(ctx, prodEnv);
assertThat(ctx.containsBean(PROD_BEAN_NAME)).isTrue();
assertThat(ctx.containsBean(DEV_BEAN_NAME)).isFalse();
assertThat(ctx.containsBean(TRANSITIVE_BEAN_NAME)).isFalse();
}
@Test
void mostSpecificDerivedClassDrivesEnvironment_withDerivedDevEnvAndDerivedDevConfigClass() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
StandardEnvironment derivedDevEnv = new StandardEnvironment();
derivedDevEnv.setActiveProfiles(DERIVED_DEV_ENV_NAME);
ctx.setEnvironment(derivedDevEnv);
ctx.register(DerivedDevConfig.class);
ctx.refresh();
assertThat(ctx.containsBean(DEV_BEAN_NAME)).isTrue();
assertThat(ctx.containsBean(DERIVED_DEV_BEAN_NAME)).isTrue();
assertThat(ctx.containsBean(TRANSITIVE_BEAN_NAME)).isTrue();
}
@Test
void mostSpecificDerivedClassDrivesEnvironment_withDevEnvAndDerivedDevConfigClass() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.setEnvironment(devEnv);
ctx.register(DerivedDevConfig.class);
ctx.refresh();
assertThat(ctx.containsBean(DEV_BEAN_NAME)).isFalse();
assertThat(ctx.containsBean(DERIVED_DEV_BEAN_NAME)).isFalse();
assertThat(ctx.containsBean(TRANSITIVE_BEAN_NAME)).isFalse();
}
@Test
void annotationConfigApplicationContext_withProfileExpressionMatchOr() {
testProfileExpression(true, "p3");
}
@Test
void annotationConfigApplicationContext_withProfileExpressionMatchAnd() {
testProfileExpression(true, "p1", "p2");
}
@Test
void annotationConfigApplicationContext_withProfileExpressionNoMatchAnd() {
testProfileExpression(false, "p1");
}
@Test
void annotationConfigApplicationContext_withProfileExpressionNoMatchNone() {
testProfileExpression(false, "p4");
}
private void testProfileExpression(boolean expected, String... activeProfiles) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
StandardEnvironment environment = new StandardEnvironment();
environment.setActiveProfiles(activeProfiles);
ctx.setEnvironment(environment);
ctx.register(ProfileExpressionConfig.class);
ctx.refresh();
assertThat(ctx.containsBean("expressionBean")).isEqualTo(expected);
}
@Test
void webApplicationContext() {
GenericWebApplicationContext ctx = new GenericWebApplicationContext(newBeanFactoryWithEnvironmentAwareBean());
assertHasStandardServletEnvironment(ctx);
ctx.setEnvironment(prodWebEnv);
ctx.refresh();
assertHasEnvironment(ctx, prodWebEnv);
assertEnvironmentBeanRegistered(ctx);
assertEnvironmentAwareInvoked(ctx, prodWebEnv);
}
@Test
void xmlWebApplicationContext() {
AbstractRefreshableWebApplicationContext ctx = new XmlWebApplicationContext();
ctx.setConfigLocation("classpath:" + XML_PATH);
ctx.setEnvironment(prodWebEnv);
ctx.refresh();
assertHasEnvironment(ctx, prodWebEnv);
assertEnvironmentBeanRegistered(ctx);
assertEnvironmentAwareInvoked(ctx, prodWebEnv);
assertThat(ctx.containsBean(DEV_BEAN_NAME)).isFalse();
assertThat(ctx.containsBean(PROD_BEAN_NAME)).isTrue();
}
@Test
void staticApplicationContext() {
StaticApplicationContext ctx = new StaticApplicationContext();
assertHasStandardEnvironment(ctx);
registerEnvironmentBeanDefinition(ctx);
ctx.setEnvironment(prodEnv);
ctx.refresh();
assertHasEnvironment(ctx, prodEnv);
assertEnvironmentBeanRegistered(ctx);
assertEnvironmentAwareInvoked(ctx, prodEnv);
}
@Test
void staticWebApplicationContext() {
StaticWebApplicationContext ctx = new StaticWebApplicationContext();
assertHasStandardServletEnvironment(ctx);
registerEnvironmentBeanDefinition(ctx);
ctx.setEnvironment(prodWebEnv);
ctx.refresh();
assertHasEnvironment(ctx, prodWebEnv);
assertEnvironmentBeanRegistered(ctx);
assertEnvironmentAwareInvoked(ctx, prodWebEnv);
}
@Test
void annotationConfigWebApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.setEnvironment(prodWebEnv);
ctx.setConfigLocation(EnvironmentAwareBean.class.getName());
ctx.refresh();
assertHasEnvironment(ctx, prodWebEnv);
assertEnvironmentBeanRegistered(ctx);
assertEnvironmentAwareInvoked(ctx, prodWebEnv);
}
@Test
void registerServletParamPropertySources_AbstractRefreshableWebApplicationContext() {
MockServletContext servletContext = new MockServletContext();
servletContext.addInitParameter("pCommon", "pCommonContextValue");
servletContext.addInitParameter("pContext1", "pContext1Value");
MockServletConfig servletConfig = new MockServletConfig(servletContext);
servletConfig.addInitParameter("pCommon", "pCommonConfigValue");
servletConfig.addInitParameter("pConfig1", "pConfig1Value");
AbstractRefreshableWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.setConfigLocation(EnvironmentAwareBean.class.getName());
ctx.setServletConfig(servletConfig);
ctx.refresh();
ConfigurableEnvironment environment = ctx.getEnvironment();
assertThat(environment).isInstanceOf(StandardServletEnvironment.class);
MutablePropertySources propertySources = environment.getPropertySources();
assertThat(propertySources.contains(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME)).isTrue();
assertThat(propertySources.contains(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME)).isTrue();
// ServletConfig gets precedence
assertThat(environment.getProperty("pCommon")).isEqualTo("pCommonConfigValue");
assertThat(propertySources.precedenceOf(PropertySource.named(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME)))
.isLessThan(propertySources.precedenceOf(PropertySource.named(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME)));
// but all params are available
assertThat(environment.getProperty("pContext1")).isEqualTo("pContext1Value");
assertThat(environment.getProperty("pConfig1")).isEqualTo("pConfig1Value");
// Servlet* PropertySources have precedence over System* PropertySources
assertThat(propertySources.precedenceOf(PropertySource.named(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME)))
.isLessThan(propertySources.precedenceOf(PropertySource.named(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME)));
// Replace system properties with a mock property source for convenience
MockPropertySource mockSystemProperties = new MockPropertySource(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME);
mockSystemProperties.setProperty("pCommon", "pCommonSysPropsValue");
mockSystemProperties.setProperty("pSysProps1", "pSysProps1Value");
propertySources.replace(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, mockSystemProperties);
// assert that servletconfig params resolve with higher precedence than sysprops
assertThat(environment.getProperty("pCommon")).isEqualTo("pCommonConfigValue");
assertThat(environment.getProperty("pSysProps1")).isEqualTo("pSysProps1Value");
}
@Test
void registerServletParamPropertySources_GenericWebApplicationContext() {
MockServletContext servletContext = new MockServletContext();
servletContext.addInitParameter("pCommon", "pCommonContextValue");
servletContext.addInitParameter("pContext1", "pContext1Value");
GenericWebApplicationContext ctx = new GenericWebApplicationContext();
ctx.setServletContext(servletContext);
ctx.refresh();
ConfigurableEnvironment environment = ctx.getEnvironment();
assertThat(environment).isInstanceOf(StandardServletEnvironment.class);
MutablePropertySources propertySources = environment.getPropertySources();
assertThat(propertySources.contains(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME)).isTrue();
// ServletContext params are available
assertThat(environment.getProperty("pCommon")).isEqualTo("pCommonContextValue");
assertThat(environment.getProperty("pContext1")).isEqualTo("pContext1Value");
// Servlet* PropertySources have precedence over System* PropertySources
assertThat(propertySources.precedenceOf(PropertySource.named(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME)))
.isLessThan(propertySources.precedenceOf(PropertySource.named(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME)));
// Replace system properties with a mock property source for convenience
MockPropertySource mockSystemProperties = new MockPropertySource(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME);
mockSystemProperties.setProperty("pCommon", "pCommonSysPropsValue");
mockSystemProperties.setProperty("pSysProps1", "pSysProps1Value");
propertySources.replace(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, mockSystemProperties);
// assert that servletcontext init params resolve with higher precedence than sysprops
assertThat(environment.getProperty("pCommon")).isEqualTo("pCommonContextValue");
assertThat(environment.getProperty("pSysProps1")).isEqualTo("pSysProps1Value");
}
@Test
void registerServletParamPropertySources_StaticWebApplicationContext() {
MockServletContext servletContext = new MockServletContext();
servletContext.addInitParameter("pCommon", "pCommonContextValue");
servletContext.addInitParameter("pContext1", "pContext1Value");
MockServletConfig servletConfig = new MockServletConfig(servletContext);
servletConfig.addInitParameter("pCommon", "pCommonConfigValue");
servletConfig.addInitParameter("pConfig1", "pConfig1Value");
StaticWebApplicationContext ctx = new StaticWebApplicationContext();
ctx.setServletConfig(servletConfig);
ctx.refresh();
ConfigurableEnvironment environment = ctx.getEnvironment();
MutablePropertySources propertySources = environment.getPropertySources();
assertThat(propertySources.contains(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME)).isTrue();
assertThat(propertySources.contains(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME)).isTrue();
// ServletConfig gets precedence
assertThat(environment.getProperty("pCommon")).isEqualTo("pCommonConfigValue");
assertThat(propertySources.precedenceOf(PropertySource.named(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME)))
.isLessThan(propertySources.precedenceOf(PropertySource.named(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME)));
// but all params are available
assertThat(environment.getProperty("pContext1")).isEqualTo("pContext1Value");
assertThat(environment.getProperty("pConfig1")).isEqualTo("pConfig1Value");
// Servlet* PropertySources have precedence over System* PropertySources
assertThat(propertySources.precedenceOf(PropertySource.named(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME)))
.isLessThan(propertySources.precedenceOf(PropertySource.named(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME)));
// Replace system properties with a mock property source for convenience
MockPropertySource mockSystemProperties = new MockPropertySource(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME);
mockSystemProperties.setProperty("pCommon", "pCommonSysPropsValue");
mockSystemProperties.setProperty("pSysProps1", "pSysProps1Value");
propertySources.replace(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, mockSystemProperties);
// assert that servletconfig params resolve with higher precedence than sysprops
assertThat(environment.getProperty("pCommon")).isEqualTo("pCommonConfigValue");
assertThat(environment.getProperty("pSysProps1")).isEqualTo("pSysProps1Value");
}
@Test
void resourceAdapterApplicationContext() {
ResourceAdapterApplicationContext ctx = new ResourceAdapterApplicationContext(new SimpleBootstrapContext(new SimpleTaskWorkManager()));
assertHasStandardEnvironment(ctx);
registerEnvironmentBeanDefinition(ctx);
ctx.setEnvironment(prodEnv);
ctx.refresh();
assertHasEnvironment(ctx, prodEnv);
assertEnvironmentBeanRegistered(ctx);
assertEnvironmentAwareInvoked(ctx, prodEnv);
}
@Test
void abstractApplicationContextValidatesRequiredPropertiesOnRefresh() {
{
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.refresh();
}
{
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setRequiredProperties("foo", "bar");
assertThatExceptionOfType(MissingRequiredPropertiesException.class).isThrownBy(
ctx::refresh);
}
{
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setRequiredProperties("foo");
ctx.setEnvironment(new MockEnvironment().withProperty("foo", "fooValue"));
ctx.refresh(); // should succeed
}
}
private DefaultListableBeanFactory newBeanFactoryWithEnvironmentAwareBean() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
registerEnvironmentBeanDefinition(bf);
return bf;
}
private void registerEnvironmentBeanDefinition(BeanDefinitionRegistry registry) {
registry.registerBeanDefinition(ENVIRONMENT_AWARE_BEAN_NAME,
rootBeanDefinition(EnvironmentAwareBean.class).getBeanDefinition());
}
private void assertEnvironmentBeanRegistered(
ConfigurableApplicationContext ctx) {
// ensure environment is registered as a bean
assertThat(ctx.containsBean(ENVIRONMENT_BEAN_NAME)).isTrue();
}
private void assertHasStandardEnvironment(ApplicationContext ctx) {
Environment defaultEnv = ctx.getEnvironment();
assertThat(defaultEnv).isNotNull();
assertThat(defaultEnv).isInstanceOf(StandardEnvironment.class);
}
private void assertHasStandardServletEnvironment(WebApplicationContext ctx) {
// ensure a default servlet environment exists
Environment defaultEnv = ctx.getEnvironment();
assertThat(defaultEnv).isNotNull();
assertThat(defaultEnv).isInstanceOf(StandardServletEnvironment.class);
}
private void assertHasEnvironment(ApplicationContext ctx, Environment expectedEnv) {
// ensure the custom environment took
Environment actualEnv = ctx.getEnvironment();
assertThat(actualEnv).isNotNull();
assertThat(actualEnv).isEqualTo(expectedEnv);
// ensure environment is registered as a bean
assertThat(ctx.containsBean(ENVIRONMENT_BEAN_NAME)).isTrue();
}
private void assertEnvironmentAwareInvoked(ConfigurableApplicationContext ctx, Environment expectedEnv) {
assertThat(ctx.getBean(EnvironmentAwareBean.class).environment).isEqualTo(expectedEnv);
}
private static class EnvironmentAwareBean implements EnvironmentAware {
public Environment environment;
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
}
/**
* Mirrors the structure of beans and environment-specific config files in
* EnvironmentSystemIntegrationTests-context.xml
*/
@Configuration
@Import({DevConfig.class, ProdConfig.class})
static class Config {
@Bean
public EnvironmentAwareBean envAwareBean() {
return new EnvironmentAwareBean();
}
}
@Profile(DEV_ENV_NAME)
@Configuration
@Import(TransitiveConfig.class)
static class DevConfig {
@Bean
public Object devBean() {
return new Object();
}
}
@Profile(PROD_ENV_NAME)
@Configuration
static class ProdConfig {
@Bean
public Object prodBean() {
return new Object();
}
}
@Configuration
static class TransitiveConfig {
@Bean
public Object transitiveBean() {
return new Object();
}
}
@Profile(DERIVED_DEV_ENV_NAME)
@Configuration
static class DerivedDevConfig extends DevConfig {
@Bean
public Object derivedDevBean() {
return new Object();
}
}
@Profile("(p1 & p2) | p3")
@Configuration
static class ProfileExpressionConfig {
@Bean
public Object expressionBean() {
return new Object();
}
}
/**
* Constants used both locally and in scan* sub-packages
*/
public static class Constants {
public static final String XML_PATH = "org/springframework/core/env/EnvironmentSystemIntegrationTests-context.xml";
public static final String ENVIRONMENT_AWARE_BEAN_NAME = "envAwareBean";
public static final String PROD_BEAN_NAME = "prodBean";
public static final String DEV_BEAN_NAME = "devBean";
public static final String DERIVED_DEV_BEAN_NAME = "derivedDevBean";
public static final String TRANSITIVE_BEAN_NAME = "transitiveBean";
public static final String PROD_ENV_NAME = "prod";
public static final String DEV_ENV_NAME = "dev";
public static final String DERIVED_DEV_ENV_NAME = "derivedDev";
}
}
@@ -1,40 +0,0 @@
/*
* Copyright 2002-2019 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
*
* https://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.core.env;
import org.junit.jupiter.api.Test;
import org.springframework.context.support.GenericApplicationContext;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition;
class PropertyPlaceholderConfigurerEnvironmentIntegrationTests {
@Test
@SuppressWarnings("deprecation")
void test() {
GenericApplicationContext ctx = new GenericApplicationContext();
ctx.registerBeanDefinition("ppc",
rootBeanDefinition(org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.class)
.addPropertyValue("searchSystemEnvironment", false)
.getBeanDefinition());
ctx.refresh();
ctx.getBean("ppc");
ctx.close();
}
}
@@ -1,26 +0,0 @@
/*
* Copyright 2002-2019 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
*
* https://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.core.env.scan1;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import({ DevConfig.class, ProdConfig.class })
class Config {
}
@@ -1,32 +0,0 @@
/*
* Copyright 2002-2019 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
*
* https://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.core.env.scan1;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Profile(org.springframework.core.env.EnvironmentSystemIntegrationTests.Constants.DEV_ENV_NAME)
@Configuration
class DevConfig {
@Bean
public Object devBean() {
return new Object();
}
}
@@ -1,32 +0,0 @@
/*
* Copyright 2002-2019 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
*
* https://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.core.env.scan1;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Profile(org.springframework.core.env.EnvironmentSystemIntegrationTests.Constants.PROD_ENV_NAME)
@Configuration
class ProdConfig {
@Bean
public Object prodBean() {
return new Object();
}
}
@@ -1,25 +0,0 @@
/*
* Copyright 2002-2019 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
*
* https://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.core.env.scan2;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
@Profile(org.springframework.core.env.EnvironmentSystemIntegrationTests.Constants.DEV_ENV_NAME)
@Component(org.springframework.core.env.EnvironmentSystemIntegrationTests.Constants.DEV_BEAN_NAME)
class DevBean {
}
@@ -1,26 +0,0 @@
/*
* Copyright 2002-2019 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
*
* https://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.core.env.scan2;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
@Profile(org.springframework.core.env.EnvironmentSystemIntegrationTests.Constants.PROD_ENV_NAME)
@Component(org.springframework.core.env.EnvironmentSystemIntegrationTests.Constants.PROD_BEAN_NAME)
class ProdBean {
}

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