Skip to content

Commit 71d2e80

Browse files
committed
Merge branch '3.0.x' into 3.1.x
2 parents 063fb21 + 0b14236 commit 71d2e80

File tree

13 files changed

+262
-112
lines changed

13 files changed

+262
-112
lines changed

grails-bootstrap/src/main/groovy/grails/io/IOUtils.groovy

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,32 @@ class IOUtils extends SpringIOUtils {
156156
return new URL("$rootPath/")
157157
}
158158
throw new IllegalStateException("Root classpath resource not found! Check your disk permissions")
159+
}
160+
159161

162+
/**
163+
* This method differs from {@link #findRootResource(java.lang.Class)} in that it will find the root URL where to load resources defined in src/main/resources
164+
*
165+
* At development time this with be build/main/resources, but in production it will be relative to the class.
166+
*
167+
* @param targetClass
168+
* @param path
169+
* @return
170+
*/
171+
static URL findRootResourcesURL(Class targetClass) {
172+
def pathToClassFile = '/' + targetClass.name.replace(".", "/") + ".class"
173+
def classRes = targetClass.getResource(pathToClassFile)
174+
if(classRes) {
175+
String rootPath = classRes.toString() - pathToClassFile
176+
if(rootPath.endsWith(BuildSettings.BUILD_CLASSES_PATH)) {
177+
rootPath = rootPath.replace('/build/classes/', '/build/resources/')
178+
}
179+
else {
180+
rootPath = "$rootPath/"
181+
}
182+
return new URL(rootPath)
183+
}
184+
return null
160185
}
161186

162187
/**
@@ -180,6 +205,7 @@ class IOUtils extends SpringIOUtils {
180205
}
181206
/**
182207
* Finds a URL within a JAR relative (from the root) to the given class
208+
*
183209
* @param targetClass
184210
* @param path
185211
* @return
@@ -197,6 +223,7 @@ class IOUtils extends SpringIOUtils {
197223
return null
198224
}
199225

226+
200227
@Memoized
201228
public static File findApplicationDirectoryFile() {
202229
def directory = findApplicationDirectory()
@@ -210,6 +237,27 @@ class IOUtils extends SpringIOUtils {
210237
return null
211238
}
212239

240+
/**
241+
* Finds the application directory for the given class
242+
*
243+
* @param targetClass The target class
244+
* @return The application directory or null if it can't be found
245+
*/
246+
public static File findApplicationDirectoryFile(Class targetClass) {
247+
248+
def rootResource = findRootResource(targetClass)
249+
if(rootResource != null) {
250+
251+
def rootFile = new UrlResource(rootResource).file.canonicalFile
252+
253+
def rootPath = rootFile.path
254+
if(rootPath.contains(BuildSettings.BUILD_CLASSES_PATH)) {
255+
return new File(rootPath - BuildSettings.BUILD_CLASSES_PATH)
256+
}
257+
}
258+
return null
259+
}
260+
213261
@Memoized
214262
public static String findApplicationDirectory() {
215263
if(applicationDirectory) {

grails-bootstrap/src/main/groovy/grails/util/BuildSettings.groovy

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,11 @@ class BuildSettings {
306306
*/
307307
public static final String BUILD_CLASSES_PATH = "build/classes/main"
308308

309+
/**
310+
* The path to the build resources directory
311+
*/
312+
public static final String BUILD_RESOURCES_PATH = "build/resources/main"
313+
309314
public static final File SETTINGS_FILE = new File("${System.getProperty('user.home')}/.grails/settings.groovy")
310315

311316
/**

grails-bootstrap/src/main/groovy/grails/util/Environment.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,8 @@ public static boolean isDevelopmentEnvironmentAvailable() {
280280
* @return True if the development sources are present
281281
*/
282282
public static boolean isDevelopmentRun() {
283-
return BuildSettings.GRAILS_APP_DIR_PRESENT && Boolean.getBoolean(RUN_ACTIVE);
283+
Environment env = Environment.getCurrent();
284+
return BuildSettings.GRAILS_APP_DIR_PRESENT && Boolean.getBoolean(RUN_ACTIVE) && (env == Environment.DEVELOPMENT);
284285
}
285286
/**
286287
* Check whether the application is deployed

grails-core/src/main/groovy/grails/boot/GrailsApp.groovy

Lines changed: 28 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import org.grails.compiler.injection.GrailsAwareInjectionOperation
2121
import org.grails.core.util.BeanCreationProfilingPostProcessor
2222
import org.grails.io.watch.DirectoryWatcher
2323
import org.grails.io.watch.FileExtensionFileChangeListener
24+
import org.grails.plugins.BinaryGrailsPlugin
2425
import org.grails.plugins.support.WatchPattern
2526
import org.grails.spring.beans.factory.OptimizedAutowireCapableBeanFactory
2627
import org.springframework.beans.factory.support.DefaultListableBeanFactory
@@ -123,53 +124,46 @@ class GrailsApp extends SpringApplication {
123124
}
124125
})
125126

127+
def pluginManager = applicationContext.getBean(GrailsPluginManager)
126128
def pluginManagerListener = createPluginManagerListener(applicationContext)
127129
directoryWatcher.addListener(pluginManagerListener)
128130

129131
File baseDir = new File(location).canonicalFile
130132

131133
List<File> watchBaseDirectories = [baseDir]
132-
def parentDir = baseDir.parentFile
133-
File settingsFile = new File(parentDir, "settings.gradle")
134-
135-
if(settingsFile.exists()) {
136-
def cc = new CompilerConfiguration()
137-
cc.scriptBaseClass = SettingsFile.name
138-
def binding = new Binding()
139-
def shell = new GroovyShell(Thread.currentThread().contextClassLoader, binding, cc)
140-
try {
141-
shell.evaluate(settingsFile)
142-
} catch (Throwable e) {
143-
// ignore
144-
}
145-
def projectPaths = binding.getVariables().get('projectPaths')
146-
if(projectPaths) {
147-
for(path in projectPaths) {
148-
if(path) {
149-
150-
def pathStr = path.toString()
151-
if(pathStr.startsWith(':')) {
152-
pathStr = pathStr.substring(1)
153-
}
154-
watchBaseDirectories << new File(parentDir, pathStr)
155-
}
134+
for(GrailsPlugin plugin in pluginManager.allPlugins) {
135+
if(plugin instanceof BinaryGrailsPlugin) {
136+
BinaryGrailsPlugin binaryGrailsPlugin = (BinaryGrailsPlugin)plugin
137+
def pluginDirectory = binaryGrailsPlugin.projectDirectory
138+
if(pluginDirectory != null) {
139+
watchBaseDirectories << pluginDirectory
156140
}
157141
}
158142
}
159143

160144
def locationLength = location.length() + 1
161-
def pluginManager = applicationContext.getBean(GrailsPluginManager)
145+
162146
for(GrailsPlugin plugin in pluginManager.allPlugins) {
163-
for(WatchPattern wp in plugin.watchedResourcePatterns) {
164-
for(watchBase in watchBaseDirectories) {
165-
if(wp.file) {
166-
def resolvedPath = new File(watchBase, wp.file.path.substring(locationLength))
167-
directoryWatcher.addWatchFile(resolvedPath)
168-
}
169-
else if(wp.directory && wp.extension) {
147+
def watchedResourcePatterns = plugin.getWatchedResourcePatterns()
148+
if(watchedResourcePatterns != null) {
149+
150+
for(WatchPattern wp in new ArrayList<WatchPattern>(watchedResourcePatterns)) {
151+
boolean first = true
152+
for(watchBase in watchBaseDirectories) {
153+
if(!first) {
154+
// the base project will already been in the list of watch patterns, but we add any subprojects here
155+
plugin.watchedResourcePatterns.add(new WatchPattern(directory: watchBase, extension: wp.extension))
156+
}
157+
first = false
158+
if(wp.file) {
159+
def resolvedPath = new File(watchBase, wp.file.path.substring(locationLength))
160+
directoryWatcher.addWatchFile(resolvedPath)
161+
}
162+
else if(wp.directory && wp.extension) {
170163

171-
def resolvedPath = new File(watchBase, wp.directory.path.substring(locationLength))
172-
directoryWatcher.addWatchDirectory(resolvedPath, wp.extension)
164+
def resolvedPath = new File(watchBase, wp.directory.path.substring(locationLength))
165+
directoryWatcher.addWatchDirectory(resolvedPath, wp.extension)
166+
}
173167
}
174168
}
175169
}

grails-core/src/main/groovy/org/grails/plugins/BinaryGrailsPlugin.java

Lines changed: 56 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.springframework.core.io.support.ResourcePatternResolver;
2626
import org.springframework.util.StringUtils;
2727

28+
import java.io.File;
2829
import java.io.IOException;
2930
import java.io.InputStream;
3031
import java.net.URL;
@@ -46,9 +47,14 @@ public class BinaryGrailsPlugin extends DefaultGrailsPlugin {
4647
public static final char UNDERSCORE = '_';
4748
public static final String PROPERTIES_EXTENSION = ".properties";
4849

49-
private BinaryGrailsPluginDescriptor descriptor;
50+
private final BinaryGrailsPluginDescriptor descriptor;
5051
private Class[] providedArtefacts = {};
51-
private Map<String, Class> precompiledViewMap = new HashMap<String, Class>();
52+
private final Map<String, Class> precompiledViewMap = new HashMap<String, Class>();
53+
private final Resource baseResource;
54+
private final Resource baseResourcesResource;
55+
private final String baseResourceString;
56+
private final boolean isJar;
57+
private final File projectDirectory;
5258

5359
/**
5460
* Creates a binary plugin instance.
@@ -60,13 +66,36 @@ public class BinaryGrailsPlugin extends DefaultGrailsPlugin {
6066
public BinaryGrailsPlugin(Class<?> pluginClass, BinaryGrailsPluginDescriptor descriptor, GrailsApplication application) {
6167
super(pluginClass, application);
6268
this.descriptor = descriptor;
69+
URL rootResource = IOUtils.findRootResource(pluginClass);
70+
if(rootResource == null) {
71+
throw new PluginException("Cannot evaluate plugin location for plugin " + pluginClass);
72+
}
73+
this.baseResource = new UrlResource(rootResource);
74+
try {
75+
this.baseResourceString = baseResource.getURL().toString();
76+
} catch (IOException e) {
77+
throw new PluginException("Cannot evaluate plugin location for plugin " + pluginClass, e);
78+
}
79+
80+
this.isJar = baseResourceString.startsWith("jar:");
81+
this.projectDirectory = isJar ? null : IOUtils.findApplicationDirectoryFile(pluginClass);
6382

83+
URL rootResourcesURL = IOUtils.findRootResourcesURL(pluginClass);
84+
if(rootResourcesURL == null) {
85+
throw new PluginException("Cannot evaluate plugin location for plugin " + pluginClass);
86+
}
87+
88+
this.baseResourcesResource= new UrlResource(rootResourcesURL);
6489
if (descriptor != null) {
6590
initializeProvidedArtefacts(descriptor.getProvidedlassNames());
6691
initializeViewMap(descriptor);
6792
}
6893
}
6994

95+
public File getProjectDirectory() {
96+
return projectDirectory;
97+
}
98+
7099
protected void initializeViewMap(BinaryGrailsPluginDescriptor descriptor) {
71100
final Resource descriptorResource = descriptor.getResource();
72101

@@ -174,7 +203,7 @@ public Resource getResource(String path) {
174203
* @return The properties or null if non exist
175204
*/
176205
public Properties getProperties(final Locale locale) {
177-
Resource url = findPluginJar();
206+
Resource url = this.baseResourcesResource;
178207
Properties properties = null;
179208
if(url != null) {
180209
StaticResourceLoader resourceLoader = new StaticResourceLoader();
@@ -183,42 +212,39 @@ public Properties getProperties(final Locale locale) {
183212
try {
184213
// first load all properties
185214
Resource[] resources = resolver.getResources('*' + PROPERTIES_EXTENSION);
186-
resources = filterResources(resources, locale);
187-
properties = new Properties();
188-
189-
Arrays.sort(resources, new Comparator<Resource>() {
190-
@Override
191-
public int compare(Resource o1, Resource o2) {
192-
String f1 = o1.getFilename();
193-
String f2 = o2.getFilename();
194-
195-
int firstUnderscoreCount = StringUtils.countOccurrencesOf(f1, "_");
196-
int secondUnderscoreCount = StringUtils.countOccurrencesOf(f2, "_");
197-
198-
if(firstUnderscoreCount == secondUnderscoreCount) {
199-
return 0;
215+
resources = resources.length > 0 ? filterResources(resources, locale) : resources;
216+
if(resources.length > 0) {
217+
properties = new Properties();
218+
219+
// message bundles are locale specific. The more underscores the locale has the more specific the locale
220+
// so we order by the number of underscores present so that the most specific appears
221+
Arrays.sort(resources, new Comparator<Resource>() {
222+
@Override
223+
public int compare(Resource o1, Resource o2) {
224+
String f1 = o1.getFilename();
225+
String f2 = o2.getFilename();
226+
227+
int firstUnderscoreCount = StringUtils.countOccurrencesOf(f1, "_");
228+
int secondUnderscoreCount = StringUtils.countOccurrencesOf(f2, "_");
229+
230+
if(firstUnderscoreCount == secondUnderscoreCount) {
231+
return 0;
232+
}
233+
else {
234+
return firstUnderscoreCount > secondUnderscoreCount ? 1 : -1;
235+
}
200236
}
201-
else {
202-
return firstUnderscoreCount > secondUnderscoreCount ? 1 : -1;
203-
}
204-
}
205-
});
237+
});
206238

207-
loadFromResources(properties, resources);
239+
loadFromResources(properties, resources);
240+
}
208241
} catch (IOException e) {
209242
return null;
210243
}
211244
}
212245
return properties;
213246
}
214247

215-
protected Resource findPluginJar() {
216-
URL url = IOUtils.findJarResource(pluginClass);
217-
if(url != null) {
218-
return new UrlResource(url);
219-
}
220-
return null;
221-
}
222248

223249
private Resource[] filterResources(Resource[] resources, Locale locale) {
224250
List<Resource> finalResources = new ArrayList<Resource>(resources.length);

grails-gradle-plugin/src/main/groovy/org/grails/gradle/plugin/agent/AgentTasksEnhancer.groovy

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,28 +34,30 @@ class AgentTasksEnhancer implements Action<Project> {
3434
private void addAgent(Project project, JavaExec exec, File agent) {
3535

3636
GrailsExtension.Agent agentConfig = project.extensions.findByType(GrailsExtension)?.agent ?: new GrailsExtension.Agent()
37+
if(agentConfig.enabled) {
38+
exec.jvmArgs "-javaagent:${agentConfig.path?.absolutePath ?: agent.absolutePath}"
3739

38-
exec.jvmArgs "-javaagent:${agentConfig.path?.absolutePath ?: agent.absolutePath}"
40+
for(arg in agentConfig.jvmArgs) {
41+
exec.jvmArgs arg
42+
}
43+
for(entry in agentConfig.systemProperties) {
44+
exec.systemProperty(entry.key, entry.value)
45+
}
3946

40-
for(arg in agentConfig.jvmArgs) {
41-
exec.jvmArgs arg
42-
}
43-
for(entry in agentConfig.systemProperties) {
44-
exec.systemProperty(entry.key, entry.value)
47+
Map<String, String> agentArgs= [
48+
inclusions: agentConfig.inclusions,
49+
synchronize: String.valueOf( agentConfig.synchronize ),
50+
allowSplitPackages: String.valueOf( agentConfig.allowSplitPackages ),
51+
cacheDir: agentConfig.cacheDir ? project.mkdir(agentConfig.cacheDir) : project.mkdir("build/springloaded")
52+
]
53+
if(agentConfig.logging != null) {
54+
agentArgs.put("logging", String.valueOf(agentConfig.logging))
55+
}
56+
if(agentConfig.exclusions) {
57+
agentArgs.put('exclusions', agentConfig.exclusions)
58+
}
59+
exec.systemProperty('springloaded', agentArgs.collect { entry -> "$entry.key=$entry.value"}.join(';'))
4560
}
4661

47-
Map<String, String> agentArgs= [
48-
inclusions: agentConfig.inclusions,
49-
synchronize: String.valueOf( agentConfig.synchronize ),
50-
allowSplitPackages: String.valueOf( agentConfig.allowSplitPackages ),
51-
cacheDir: agentConfig.cacheDir ? project.mkdir(agentConfig.cacheDir) : project.mkdir("build/springloaded")
52-
]
53-
if(agentConfig.logging != null) {
54-
agentArgs.put("logging", String.valueOf(agentConfig.logging))
55-
}
56-
if(agentConfig.exclusions) {
57-
agentArgs.put('exclusions', agentConfig.exclusions)
58-
}
59-
exec.systemProperty('springloaded', agentArgs.collect { entry -> "$entry.key=$entry.value"}.join(';'))
6062
}
6163
}

0 commit comments

Comments
 (0)