Skip to content
This repository
  • 4 commits
  • 13 files changed
  • 0 comments
  • 1 contributor
Apr 17, 2012
Ben Browning bbrowning Remove VFSLoadService in favor of NonLeakingLoadService (TORQUE-775)
This is not only because I enjoy prefixing more classes with
NonLeaking, which I do, but also to greatly simplify our custom
LoadService logic. All VFS references are removed and no longer
needed, at least according to our unit and integration tests.

This is the first of several changes to get TorqueBox working with
JRuby 1.6.7 and 1.7.
ca076f9
Ben Browning bbrowning Use reflection in ScriptAnalyzer so it works under JRuby 1.7 (TORQUE-…
…775)

We should figure out why LocalStaticScope's constructor is no longer
public in JRuby 1.7 and either adjust our code or submit a patch to
make it public again.
188a8a4
Ben Browning bbrowning Can't inject messaging destinations without torquebox-messaging avail…
…able (TORQUE-775)

JRuby's LoadService is more strict and correct, in this case. This
shouldn't have worked before but it did. You always need the torquebox
or torquebox-messaging gem in your Gemfile to inject messaging
destinations, since they call code inside the TorqueBox::Messaging module.
984ba7b
Apr 18, 2012
Ben Browning bbrowning Don't require torquebox-web since RackRuntimeInitializer does (TORQUE…
…-775)

The require is harmless under 1.8 but due to a bug in JRuby's 1.9
LoadService implementation (JRUBY-6610) this throws a LoadError if
Bundler is used and torquebox or torquebox-web are not in the app's
Gemfile. Since torquebox-web is already required by
RackRuntimeInitializer, this was a no-op anyway.
70f4c04
3  integration-tests/apps/padrino/injection/Gemfile
... ... @@ -1,3 +1,4 @@
  1 +source "file://#{File.dirname(__FILE__)}/../../../../assemblage/assembly/target/stage/gem-repo"
1 2 source :rubygems
2 3
3 4 # Server requirements (defaults to WEBrick)
@@ -23,3 +24,5 @@ gem 'padrino', '0.10.5'
23 24 # %w(core gen helpers cache mailer admin).each do |g|
24 25 # gem 'padrino-' + g, '0.10.5'
25 26 # end
  27 +
  28 +gem 'torquebox'
41 modules/core/src/main/java/org/torquebox/core/analysis/ScriptAnalyzer.java
@@ -21,6 +21,8 @@
21 21
22 22 import java.io.IOException;
23 23 import java.io.InputStream;
  24 +import java.lang.reflect.Constructor;
  25 +import java.lang.reflect.InvocationTargetException;
24 26
25 27 import org.jboss.logging.Logger;
26 28 import org.jboss.vfs.VirtualFile;
@@ -135,22 +137,33 @@ public void analyze(String filename, InputStream in, NodeVisitor visitor, Versio
135 137 * @return The result provided by the specific <code>NodeVisitor</code>.
136 138 */
137 139 public void analyze(String filename, String script, NodeVisitor visitor, Version rubyVersion) {
138   - StaticScope staticScope = new LocalStaticScope( null );
139   - DynamicScope scope = new ManyVarsDynamicScope( staticScope );
140   - Ruby analyzingRuby = null;
141   -
142   - if (rubyVersion.equals( Version.V1_8 )) {
143   - analyzingRuby = this.ruby18;
144   - } else if (rubyVersion.equals( Version.V1_9 )) {
145   - analyzingRuby = this.ruby19;
146   - }
147   -
148 140 try {
149   - Node result = analyzingRuby.parseEval( script, filename, scope, 0 );
150   - result.accept( visitor );
151   - } catch(RaiseException ex) {
152   - log.trace( "JRuby exception when parsing file " + filename , ex );
  141 + // Temporary reflection hack until LocalStaticScope's constructor is visible again
  142 + Constructor<LocalStaticScope> constructor = LocalStaticScope.class.getDeclaredConstructor( StaticScope.class );
  143 + constructor.setAccessible( true );
  144 + StaticScope staticScope = constructor.newInstance( new Object[] { null } );
  145 + DynamicScope scope = new ManyVarsDynamicScope( staticScope );
  146 + Ruby analyzingRuby = null;
  147 +
  148 + if (rubyVersion.equals( Version.V1_8 )) {
  149 + analyzingRuby = this.ruby18;
  150 + } else if (rubyVersion.equals( Version.V1_9 )) {
  151 + analyzingRuby = this.ruby19;
  152 + }
  153 +
  154 + try {
  155 + Node result = analyzingRuby.parseEval( script, filename, scope, 0 );
  156 + result.accept( visitor );
  157 + } catch(RaiseException ex) {
  158 + log.trace( "JRuby exception when parsing file " + filename , ex );
  159 + }
153 160 }
  161 + // Catch the reflection-related exceptions until LocalStaticScope's
  162 + // constructor is public again
  163 + catch (NoSuchMethodException e) {}
  164 + catch (InvocationTargetException e) {}
  165 + catch (IllegalAccessException e) {}
  166 + catch (InstantiationException e) {}
154 167 }
155 168
156 169 /**
59 modules/core/src/main/java/org/torquebox/core/runtime/NonLeakingLoadService.java
... ... @@ -0,0 +1,59 @@
  1 +/*
  2 + * Copyright 2008-2012 Red Hat, Inc, and individual contributors.
  3 + *
  4 + * This is free software; you can redistribute it and/or modify it
  5 + * under the terms of the GNU Lesser General Public License as
  6 + * published by the Free Software Foundation; either version 2.1 of
  7 + * the License, or (at your option) any later version.
  8 + *
  9 + * This software is distributed in the hope that it will be useful,
  10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12 + * Lesser General Public License for more details.
  13 + *
  14 + * You should have received a copy of the GNU Lesser General Public
  15 + * License along with this software; if not, write to the Free
  16 + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  17 + * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  18 + */
  19 +
  20 +package org.torquebox.core.runtime;
  21 +
  22 +import java.io.IOException;
  23 +
  24 +import org.jruby.Ruby;
  25 +import org.jruby.runtime.load.LoadService;
  26 +import org.jruby.runtime.load.LoadServiceResource;
  27 +
  28 +public class NonLeakingLoadService extends LoadService {
  29 +
  30 + public NonLeakingLoadService(Ruby runtime) {
  31 + super( runtime );
  32 + }
  33 +
  34 + @Override
  35 + protected LoadServiceResource tryResourceFromJarURL(SearchState state, String baseName, SuffixType suffixType) {
  36 + return wrapLeakingResource( super.tryResourceFromJarURL( state, baseName, suffixType ) );
  37 + }
  38 +
  39 + @Override
  40 + protected LoadServiceResource tryResourceFromJarURLWithLoadPath(String namePlusSuffix, String loadPathEntry) {
  41 + return wrapLeakingResource( super.tryResourceFromJarURLWithLoadPath( namePlusSuffix, loadPathEntry ) );
  42 + }
  43 +
  44 + @Override
  45 + protected LoadServiceResource getClassPathResource(ClassLoader classLoader, String name) {
  46 + return wrapLeakingResource( super.getClassPathResource( classLoader, name ) );
  47 + };
  48 +
  49 + static LoadServiceResource wrapLeakingResource(LoadServiceResource resource) {
  50 + if (resource == null) {
  51 + return null;
  52 + }
  53 + try {
  54 + return new NonLeakingLoadServiceResource( resource.getURL(), resource.getName(), resource.isAbsolute() );
  55 + } catch (IOException e) {
  56 + return resource;
  57 + }
  58 + }
  59 +}
51 modules/core/src/main/java/org/torquebox/core/runtime/NonLeakingLoadService19.java
... ... @@ -0,0 +1,51 @@
  1 +/*
  2 + * Copyright 2008-2012 Red Hat, Inc, and individual contributors.
  3 + *
  4 + * This is free software; you can redistribute it and/or modify it
  5 + * under the terms of the GNU Lesser General Public License as
  6 + * published by the Free Software Foundation; either version 2.1 of
  7 + * the License, or (at your option) any later version.
  8 + *
  9 + * This software is distributed in the hope that it will be useful,
  10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12 + * Lesser General Public License for more details.
  13 + *
  14 + * You should have received a copy of the GNU Lesser General Public
  15 + * License along with this software; if not, write to the Free
  16 + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  17 + * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  18 + */
  19 +
  20 +package org.torquebox.core.runtime;
  21 +
  22 +import org.jruby.Ruby;
  23 +import org.jruby.runtime.load.LoadService19;
  24 +import org.jruby.runtime.load.LoadServiceResource;
  25 +
  26 +public class NonLeakingLoadService19 extends LoadService19 {
  27 +
  28 + public NonLeakingLoadService19(Ruby runtime) {
  29 + super( runtime );
  30 + }
  31 +
  32 + @Override
  33 + protected LoadServiceResource tryResourceFromJarURL(SearchState state, String baseName, SuffixType suffixType) {
  34 + return wrapLeakingResource( super.tryResourceFromJarURL( state, baseName, suffixType ) );
  35 + }
  36 +
  37 + @Override
  38 + protected LoadServiceResource tryResourceFromJarURLWithLoadPath(String namePlusSuffix, String loadPathEntry) {
  39 + return wrapLeakingResource( super.tryResourceFromJarURLWithLoadPath( namePlusSuffix, loadPathEntry ) );
  40 + }
  41 +
  42 + @Override
  43 + protected LoadServiceResource getClassPathResource(ClassLoader classLoader, String name) {
  44 + return wrapLeakingResource( super.getClassPathResource( classLoader, name ) );
  45 + }
  46 +
  47 + protected LoadServiceResource wrapLeakingResource(LoadServiceResource resource) {
  48 + return NonLeakingLoadService.wrapLeakingResource( resource );
  49 + }
  50 +
  51 +}
17 ...torquebox/core/runtime/VFSLoadServiceCreator.java → ...ox/core/runtime/NonLeakingLoadServiceCreator.java
@@ -23,18 +23,13 @@
23 23 import org.jruby.RubyInstanceConfig.LoadServiceCreator;
24 24 import org.jruby.runtime.load.LoadService;
25 25
26   -/**
27   - * Factory for {@link VFSLoadService}.
28   - *
29   - * @see VFSLoadService
30   - *
31   - * @author Bob McWhirter <bmcwhirt@redhat.com>
32   - */
33   -public class VFSLoadServiceCreator implements LoadServiceCreator {
  26 +public class NonLeakingLoadServiceCreator implements LoadServiceCreator {
34 27
35   - @Override
36   - public LoadService create(Ruby ruby) {
37   - return new VFSLoadService( ruby );
  28 + public LoadService create(Ruby runtime) {
  29 + if (runtime.is1_9()) {
  30 + return new NonLeakingLoadService19(runtime);
  31 + }
  32 + return new NonLeakingLoadService(runtime);
38 33 }
39 34
40 35 }
31 modules/core/src/main/java/org/torquebox/core/runtime/RubyRuntimeFactory.java
@@ -32,15 +32,10 @@
32 32 import java.util.List;
33 33 import java.util.Map;
34 34 import java.util.Set;
35   -import java.util.concurrent.Executors;
36   -import java.util.concurrent.ScheduledExecutorService;
37 35
38 36 import org.jboss.logging.Logger;
39 37 import org.jboss.msc.inject.Injector;
40 38 import org.jboss.msc.service.ServiceRegistry;
41   -import org.jboss.vfs.TempFileProvider;
42   -import org.jboss.vfs.VFS;
43   -import org.jboss.vfs.VirtualFile;
44 39 import org.jruby.CompatVersion;
45 40 import org.jruby.Ruby;
46 41 import org.jruby.RubyInstanceConfig;
@@ -263,7 +258,7 @@ public Ruby createInstance(String contextInfo, boolean initialize) throws Except
263 258
264 259 config.setLoader( getClassLoader() );
265 260 // config.setClassCache( getClassCache() );
266   - config.setLoadServiceCreator( new VFSLoadServiceCreator() );
  261 + config.setLoadServiceCreator( new NonLeakingLoadServiceCreator() );
267 262 if (this.rubyVersion != null) {
268 263 config.setCompatVersion( this.rubyVersion );
269 264 }
@@ -346,29 +341,7 @@ private String attemptMountJRubyHomeFromClassPath() throws URISyntaxException, I
346 341 String internalJRubyHome = RubyInstanceConfig.class.getResource( "/META-INF/jruby.home" ).toURI().getSchemeSpecificPart();
347 342
348 343 if (internalJRubyHome.startsWith( "file:" ) && internalJRubyHome.contains( "!/" )) {
349   - int slashLoc = internalJRubyHome.indexOf( '/' );
350   - int bangLoc = internalJRubyHome.indexOf( '!' );
351   -
352   - String jarPath = internalJRubyHome.substring( slashLoc, bangLoc );
353   -
354   - String extraPath = internalJRubyHome.substring( bangLoc + 1 );
355   -
356   - VirtualFile vfsJar = VFS.getChild( jarPath );
357   -
358   - if (vfsJar.exists()) {
359   - if (!vfsJar.isDirectory()) {
360   - ScheduledExecutorService executor = Executors.newScheduledThreadPool( 1 );
361   - TempFileProvider tempFileProvider = TempFileProvider.create( "jruby.home", executor );
362   - this.mountedJRubyHomes.add( VFS.mountZip( vfsJar, vfsJar, tempFileProvider ) );
363   - }
364   -
365   - if (vfsJar.isDirectory()) {
366   - VirtualFile vfsJrubyHome = vfsJar.getChild( extraPath );
367   - if (vfsJrubyHome.exists()) {
368   - return vfsJrubyHome.toURL().toExternalForm();
369   - }
370   - }
371   - }
  344 + return internalJRubyHome;
372 345 }
373 346
374 347 return null;
366 modules/core/src/main/java/org/torquebox/core/runtime/VFSLoadService.java
... ... @@ -1,366 +0,0 @@
1   -/*
2   - * Copyright 2008-2012 Red Hat, Inc, and individual contributors.
3   - *
4   - * This is free software; you can redistribute it and/or modify it
5   - * under the terms of the GNU Lesser General Public License as
6   - * published by the Free Software Foundation; either version 2.1 of
7   - * the License, or (at your option) any later version.
8   - *
9   - * This software is distributed in the hope that it will be useful,
10   - * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   - * Lesser General Public License for more details.
13   - *
14   - * You should have received a copy of the GNU Lesser General Public
15   - * License along with this software; if not, write to the Free
16   - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17   - * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
18   - */
19   -
20   -package org.torquebox.core.runtime;
21   -
22   -import java.io.File;
23   -import java.io.IOException;
24   -import java.net.MalformedURLException;
25   -import java.net.URISyntaxException;
26   -import java.net.URL;
27   -import java.util.Iterator;
28   -
29   -import org.jboss.vfs.VFS;
30   -import org.jboss.vfs.VirtualFile;
31   -import org.jruby.Ruby;
32   -import org.jruby.RubyFile;
33   -import org.jruby.exceptions.RaiseException;
34   -import org.jruby.runtime.builtin.IRubyObject;
35   -import org.jruby.runtime.load.Library;
36   -import org.jruby.runtime.load.LoadService;
37   -import org.jruby.runtime.load.LoadServiceResource;
38   -import org.jruby.util.JRubyFile;
39   -
40   -/**
41   - * VFS-enabled {@link LoadService}
42   - *
43   - * @author Bob McWhirter <bmcwhirt@redhat.com>
44   - */
45   -public class VFSLoadService extends LoadService {
46   -
47   - {
48   - for (int i = 0; i < searchers.size(); ++i) {
49   - if (searchers.get( i ) instanceof NormalSearcher) {
50   - searchers.set( i, new VFSSearcher() );
51   - }
52   - }
53   - }
54   -
55   - public class VFSSearcher implements LoadSearcher {
56   -
57   - @Override
58   - public boolean shouldTrySearch(SearchState state) {
59   - return state.library == null;
60   - }
61   -
62   - @Override
63   - public void trySearch(SearchState state) throws AlreadyLoaded {
64   - state.library = findLibraryWithoutCWD( state, state.searchFile, state.suffixType );
65   - }
66   -
67   - }
68   -
69   - public VFSLoadService(Ruby runtime) {
70   - super( runtime );
71   - }
72   -
73   - URL makeUrl(String base, String path) throws MalformedURLException {
74   -
75   - base = base.replaceAll( "\\/\\/+", "/" );
76   - path = path.replaceAll( "\\/\\/+", "/" );
77   - if (!base.endsWith( "/" )) {
78   - base = base + "/";
79   - }
80   -
81   - if (base.startsWith( "vfs:" )) {
82   - return new URL( new URL( base ), path );
83   - }
84   -
85   - if (base.startsWith( "/" )) {
86   - return new URL( new URL( "file:" + base ), path );
87   - }
88   -
89   - return null;
90   - }
91   -
92   - protected Library findLibraryWithoutCWD(SearchState state, String baseName, SuffixType suffixType) {
93   - //System.err.println("findLibraryWithoutCWD(" + baseName + "," +
94   - //suffixType + ")");
95   - Library library = null;
96   -
97   - switch (suffixType) {
98   - case Both:
99   - library = findBuiltinLibrary( state, baseName, SuffixType.Source );
100   - if (library == null)
101   - library = createLibrary( state, tryResourceFromLoadPathOrURL( state, baseName, SuffixType.Source ) );
102   - // If we fail to find as a normal Ruby script, we try to find as an
103   - // extension,
104   - // checking for a builtin first.
105   - if (library == null)
106   - library = findBuiltinLibrary( state, baseName, SuffixType.Extension );
107   - if (library == null)
108   - library = createLibrary( state, tryResourceFromLoadPathOrURL( state, baseName, SuffixType.Extension ) );
109   - break;
110   - case Source:
111   - case Extension:
112   - // Check for a builtin first.
113   - library = findBuiltinLibrary( state, baseName, suffixType );
114   - if (library == null)
115   - library = createLibrary( state, tryResourceFromLoadPathOrURL( state, baseName, suffixType ) );
116   - break;
117   - case Neither:
118   - if (library == null)
119   - library = createLibrary( state, tryResourceFromLoadPathOrURL( state, baseName, SuffixType.Neither ) );
120   - break;
121   - }
122   -
123   - return library;
124   - }
125   -
126   - @SuppressWarnings("rawtypes")
127   - protected LoadServiceResource tryResourceFromLoadPathOrURL(SearchState state, String baseName, SuffixType suffixType) {
128   - //System.err.println("tryResourceFromLoadPathOrUrl(" + baseName + "," +
129   - //suffixType + ")");
130   - LoadServiceResource foundResource = null;
131   -
132   - // if it's a ./ baseName, use CWD logic
133   - if (baseName.startsWith( "./" )) {
134   - foundResource = tryResourceFromCWD( state, baseName, suffixType );
135   -
136   - if (foundResource != null) {
137   - state.loadName = foundResource.getName();
138   - return foundResource;
139   - }
140   - }
141   -
142   - // if given path is absolute, just try it as-is (with extensions) and no
143   - // load path
144   - if (new File( baseName ).isAbsolute() || baseName.startsWith( "vfs:" )) {
145   - for (String suffix : suffixType.getSuffixes()) {
146   - String namePlusSuffix = baseName + suffix;
147   - foundResource = tryResourceAsIs( namePlusSuffix );
148   -
149   - if (foundResource != null) {
150   - state.loadName = namePlusSuffix;
151   - return foundResource;
152   - }
153   - }
154   -
155   - return null;
156   - }
157   -
158   - Outer: for (Iterator pathIter = loadPath.getList().iterator(); pathIter.hasNext();) {
159   - // TODO this is really ineffient, and potentially a problem
160   - // everytime anyone require's something.
161   - // we should try to make LoadPath a special array object.
162   - String loadPathEntry = ((IRubyObject) pathIter.next()).toString();
163   -
164   - if (loadPathEntry.equals( "." )) {
165   - foundResource = tryResourceFromCWD( state, baseName, suffixType );
166   -
167   - if (foundResource != null) {
168   - state.loadName = foundResource.getName();
169   - break Outer;
170   - }
171   - } else {
172   - for (String suffix : suffixType.getSuffixes()) {
173   - String namePlusSuffix = baseName + suffix;
174   - foundResource = tryResourceFromLoadPath( namePlusSuffix, loadPathEntry );
175   -
176   - if (foundResource != null) {
177   - state.loadName = namePlusSuffix;
178   - break Outer; // end suffix iteration
179   - }
180   - }
181   - }
182   - }
183   -
184   - return foundResource;
185   - }
186   -
187   - protected LoadServiceResource tryResourceFromLoadPath(String namePlusSuffix, String loadPathEntry) throws RaiseException {
188   - //System.err.println("tryResourceFromLoadPath(" + namePlusSuffix + ","
189   - //+ loadPathEntry + ")");
190   - LoadServiceResource foundResource = null;
191   -
192   - try {
193   - if (!Ruby.isSecurityRestricted()) {
194   -
195   - if (loadPathEntry.startsWith( "vfs:" )) {
196   - try {
197   - URL vfsUrl = makeUrl( loadPathEntry, namePlusSuffix );
198   - VirtualFile file = VFS.getChild( vfsUrl.toURI() );
199   - if (file != null && file.exists()) {
200   - return unVFSifiedResource( file );
201   - //return new NonLeakingLoadServiceResource( file.toURI().toURL(), vfsUrl.toExternalForm() );
202   - }
203   - return null;
204   - } catch (IOException e) {
205   - e.printStackTrace();
206   - } catch (URISyntaxException e) {
207   - e.printStackTrace();
208   - }
209   - }
210   -
211   - String reportedPath = loadPathEntry + "/" + namePlusSuffix;
212   - JRubyFile actualPath = null;
213   - // we check length == 0 for 'load', which does not use load path
214   - if (new File( reportedPath ).isAbsolute()) {
215   - // it's an absolute path, use it as-is
216   - actualPath = JRubyFile.create( loadPathEntry, RubyFile.expandUserPath( runtime.getCurrentContext(), namePlusSuffix ) );
217   - } else {
218   - // prepend ./ if . is not already there, since we're loading
219   - // based on CWD
220   - if (reportedPath.charAt( 0 ) != '.') {
221   - reportedPath = "./" + reportedPath;
222   - }
223   - actualPath = JRubyFile.create( JRubyFile.create( runtime.getCurrentDirectory(), loadPathEntry ).getAbsolutePath(),
224   - RubyFile.expandUserPath( runtime.getCurrentContext(), namePlusSuffix ) );
225   - }
226   - if (actualPath.isFile()) {
227   - try {
228   - foundResource = new NonLeakingLoadServiceResource( actualPath.toURI().toURL(), reportedPath );
229   - } catch (MalformedURLException e) {
230   - throw runtime.newIOErrorFromException( e );
231   - }
232   - }
233   - }
234   - } catch (SecurityException secEx) {
235   - }
236   -
237   - return foundResource;
238   - }
239   -
240   - protected LoadServiceResource tryResourceAsIs(String namePlusSuffix) throws RaiseException {
241   - //System.err.println("tryResourceAsIs(" + namePlusSuffix + ")");
242   - LoadServiceResource foundResource = null;
243   -
244   - try {
245   - if (!Ruby.isSecurityRestricted()) {
246   - String reportedPath = namePlusSuffix;
247   - // we check length == 0 for 'load', which does not use load path
248   - if (reportedPath.startsWith( "vfs:" )) {
249   - try {
250   - URL vfsUrl = new URL( reportedPath );
251   - // VirtualFile file = VFS.getRoot(vfsUrl);
252   - VirtualFile file = VFS.getChild( vfsUrl.toURI() );
253   - if (file != null && file.exists()) {
254   - return unVFSifiedResource( file );
255   - //return new NonLeakingLoadServiceResource( file.toURI().toURL(), reportedPath );
256   - }
257   - } catch (IOException e) {
258   - // ignore
259   - } catch (URISyntaxException e) {
260   - // ignore
261   - }
262   - return null;
263   - }
264   -
265   - File actualPath = null;
266   - if (new File( reportedPath ).isAbsolute()) {
267   - actualPath = new File( RubyFile.expandUserPath( runtime.getCurrentContext(), namePlusSuffix ) );
268   - } else {
269   - // prepend ./ if . is not already there, since we're loading
270   - // based on CWD
271   - if (reportedPath.charAt( 0 ) == '.' && reportedPath.charAt( 1 ) == '/') {
272   - reportedPath = reportedPath.replaceFirst( "\\./", runtime.getCurrentDirectory() );
273   - }
274   - actualPath = new File( RubyFile.expandUserPath( runtime.getCurrentContext(), reportedPath ) );
275   - }
276   - if (actualPath.isFile()) {
277   - try {
278   - foundResource = new NonLeakingLoadServiceResource( actualPath.toURI().toURL(), reportedPath );
279   - } catch (MalformedURLException e) {
280   - throw runtime.newIOErrorFromException( e );
281   - }
282   - }
283   - }
284   - } catch (SecurityException secEx) {
285   - // ignore
286   - }
287   -
288   - return foundResource;
289   - }
290   -
291   - public void load(String file, boolean wrap) {
292   - //System.err.println("load(" + file + ")");
293   - if (!runtime.getProfile().allowLoad( file )) {
294   - throw runtime.newLoadError( "No such file to load -- " + file );
295   - }
296   -
297   - SearchState state = new SearchState( file );
298   - state.prepareLoadSearch( file );
299   -
300   - Library library = findBuiltinLibrary( state, state.searchFile, state.suffixType );
301   - if (library == null)
302   - library = findLibraryWithoutCWD( state, state.searchFile, state.suffixType );
303   -
304   - if (library == null) {
305   - library = findLibraryWithClassloaders( state, state.searchFile, state.suffixType );
306   - if (library == null) {
307   - throw runtime.newLoadError( "No such file to load -- " + file );
308   - }
309   - }
310   - try {
311   - library.load( runtime, wrap );
312   - } catch (IOException e) {
313   - if (runtime.getDebug().isTrue())
314   - e.printStackTrace( runtime.getErr() );
315   - throw runtime.newLoadError( "IO error -- " + file );
316   - }
317   - }
318   -
319   - protected LoadServiceResource tryResourceFromCWD(SearchState state, String baseName, SuffixType suffixType) throws RaiseException {
320   - LoadServiceResource foundResource = null;
321   -
322   - for (String suffix : suffixType.getSuffixes()) {
323   - String namePlusSuffix = baseName + suffix;
324   - // check current directory; if file exists, retrieve URL and return
325   - // resource
326   - try {
327   - JRubyFile file = JRubyFile.create( runtime.getCurrentDirectory(), RubyFile.expandUserPath( runtime.getCurrentContext(), namePlusSuffix ) );
328   - debugLogTry( "resourceFromCWD", file.toString() );
329   - if (file.isFile() && file.isAbsolute() && file.canRead()) {
330   - boolean absolute = true;
331   - String s = namePlusSuffix;
332   - if (!namePlusSuffix.startsWith( "./" )) {
333   - s = "./" + s;
334   - }
335   - foundResource = new NonLeakingLoadServiceResource( file.toURI().toURL(), s, absolute );
336   - debugLogFound( foundResource );
337   - state.loadName = resolveLoadName( foundResource, namePlusSuffix );
338   - break;
339   - }
340   - } catch (IllegalArgumentException illArgEx) {
341   - } catch (SecurityException secEx) {
342   - } catch (IOException ioEx) {
343   - }
344   - }
345   -
346   - return foundResource;
347   - }
348   -
349   - protected NonLeakingLoadServiceResource unVFSifiedResource(VirtualFile vFile) throws IOException {
350   - File file = vFile.getPhysicalFile();
351   - return new NonLeakingLoadServiceResource( file.toURI().toURL(), file.getAbsolutePath() );
352   - }
353   -
354   - /*
355   - * @Override protected void addLoadedFeature(RubyString loadNameRubyString)
356   - * { System.err.println( "addLoadedFeature(" + loadNameRubyString + ")" );
357   - * super.addLoadedFeature(loadNameRubyString); }
358   - *
359   - * @Override protected boolean featureAlreadyLoaded(RubyString
360   - * loadNameRubyString) { boolean result =
361   - * super.featureAlreadyLoaded(loadNameRubyString); System.err.println(
362   - * "featureAlreadyLoaded(" + loadNameRubyString + ") " + result ); return
363   - * result; }
364   - */
365   -
366   -}
35 ...x/core/runtime/VFSLoadServiceWithRuntimeTest.java → ...uebox/core/runtime/NonLeakingLoadServiceTest.java
@@ -23,12 +23,14 @@
23 23
24 24 import org.jruby.Ruby;
25 25 import org.jruby.runtime.builtin.IRubyObject;
  26 +import org.jruby.runtime.load.LoadService;
26 27 import org.junit.Before;
  28 +import org.junit.Ignore;
27 29 import org.junit.Test;
28 30
29   -public class VFSLoadServiceWithRuntimeTest {
30   -
31   - private VFSLoadService loadService;
  31 +public class NonLeakingLoadServiceTest {
  32 +
  33 + private LoadService loadService;
32 34 private Ruby ruby;
33 35
34 36 @Before
@@ -36,14 +38,35 @@ public void setUp() throws Exception {
36 38 RubyRuntimeFactory factory = new RubyRuntimeFactory();
37 39 factory.setUseJRubyHomeEnvVar( false );
38 40 this.ruby = factory.createInstance( "test" );
39   - this.loadService = (VFSLoadService) this.ruby.getLoadService();
  41 + this.loadService = ruby.getLoadService();
40 42 }
41 43
42 44 @Test
43   - public void testRubygemsLoadable() throws Exception {
  45 + public void testRubygemsLoadable() {
44 46 this.loadService.require( "rubygems" );
45   - IRubyObject result = this.ruby.evalScriptlet( "Gem" );
  47 + IRubyObject result = this.ruby.evalScriptlet( "Gem" );
  48 + assertNotNull( result );
  49 + }
  50 +
  51 + @Test
  52 + public void testClasspathLoadable() {
  53 + this.loadService.require( "dummy" );
  54 + IRubyObject result = this.ruby.evalScriptlet( "Dummy" );
46 55 assertNotNull( result );
47 56 }
48 57
  58 + @Test
  59 + @Ignore( "only run locally" )
  60 + /**
  61 + * Used only in manual testing to verify we're not leaking input streams
  62 + * when loading dummy.rb - lsof -p <pid> of test process to see number of
  63 + * references to dummy.rb. It's always 0 when fixed, double digits when leaking.
  64 + */
  65 + public void testNoLeaks() throws Exception {
  66 + for(int i = 0; i < 100000; i++) {
  67 + loadService.require( "dummy.rb" );
  68 + loadService.removeInternalLoadedFeature( "dummy.rb" );
  69 + }
  70 + }
  71 +
49 72 }
79 modules/core/src/test/java/org/torquebox/core/runtime/VFSLoadServiceTest.java
... ... @@ -1,79 +0,0 @@
1   -/*
2   - * Copyright 2008-2012 Red Hat, Inc, and individual contributors.
3   - *
4   - * This is free software; you can redistribute it and/or modify it
5   - * under the terms of the GNU Lesser General Public License as
6   - * published by the Free Software Foundation; either version 2.1 of
7   - * the License, or (at your option) any later version.
8   - *
9   - * This software is distributed in the hope that it will be useful,
10   - * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   - * Lesser General Public License for more details.
13   - *
14   - * You should have received a copy of the GNU Lesser General Public
15   - * License along with this software; if not, write to the Free
16   - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17   - * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
18   - */
19   -
20   -package org.torquebox.core.runtime;
21   -
22   -import static org.junit.Assert.assertEquals;
23   -
24   -import org.jboss.vfs.VFS;
25   -import org.junit.Before;
26   -import org.junit.Test;
27   -
28   -public class VFSLoadServiceTest {
29   -
30   - private VFSLoadService loadService;
31   -
32   - @Before
33   - public void setUp() {
34   - // Force VFS url-handler init.
35   - VFS.getRootVirtualFile();
36   - this.loadService = new VFSLoadService( null );
37   - }
38   -
39   - @Test
40   - public void testMakeUrlNonVfsBaseWithoutSlash() throws Exception {
41   - String base = "/Users/bob/myapp";
42   - String path = "app/controllers/foo_controller.rb";
43   -
44   - String url = this.loadService.makeUrl( base, path ).toString();
45   -
46   - assertEquals( "file:/Users/bob/myapp/app/controllers/foo_controller.rb", url );
47   - }
48   -
49   - @Test
50   - public void testMakeUrlNonVfsBaseWithSlash() throws Exception {
51   - String base = "/Users/bob/myapp/";
52   - String path = "app/controllers/foo_controller.rb";
53   -
54   - String url = this.loadService.makeUrl( base, path ).toString();
55   -
56   - assertEquals( "file:/Users/bob/myapp/app/controllers/foo_controller.rb", url );
57   - }
58   -
59   - @Test
60   - public void testMakeUrlVfsBaseWithoutSlash() throws Exception {
61   - String base = "vfs:/Users/bob/myapp";
62   - String path = "app/controllers/foo_controller.rb";
63   -
64   - String url = this.loadService.makeUrl( base, path ).toString();
65   -
66   - assertEquals( "vfs:/Users/bob/myapp/app/controllers/foo_controller.rb", url );
67   - }
68   -
69   - @Test
70   - public void testMakeUrlVfsBaseWithSlash() throws Exception {
71   - String base = "vfs:/Users/bob/myapp/";
72   - String path = "app/controllers/foo_controller.rb";
73   -
74   - String url = this.loadService.makeUrl( base, path ).toString();
75   -
76   - assertEquals( "vfs:/Users/bob/myapp/app/controllers/foo_controller.rb", url );
77   - }
78   -
79   -}
2  modules/core/src/test/resources/dummy.rb
... ... @@ -0,0 +1,2 @@
  1 +class Dummy
  2 +end
2  modules/messaging/src/main/java/org/torquebox/messaging/injection/LiveDestination.java
@@ -44,7 +44,7 @@ public Destination getDestination() {
44 44
45 45 @Override
46 46 public Object convert(Ruby ruby) throws Exception {
47   - IRubyObject gemRequired = RuntimeHelper.evalScriptlet( ruby, "begin; require %q(torquebox-messaging); true; rescue LoadError; false; end" );
  47 + IRubyObject gemRequired = RuntimeHelper.evalScriptlet( ruby, "begin; require %q(torquebox-messaging); true; rescue LoadError; $stderr.puts 'ERROR: torquebox-messaging gem not loaded - skipping destination injection'; false; end" );
48 48 if (!gemRequired.isTrue()) {
49 49 return null;
50 50 }
2  modules/messaging/src/test/java/org/torquebox/messaging/component/MessageProcessorComponentTest.java
@@ -45,7 +45,7 @@ public void setUp() throws Exception {
45 45 this.ruby = createRuby();
46 46
47 47 URL rb = getClass().getResource( "test_message_processor.rb" );
48   - this.ruby.getLoadService().require( rb.toString() );
  48 + this.ruby.getLoadService().require( rb.getPath() );
49 49
50 50 this.rubyProcessor = RuntimeHelper.instantiate( ruby, "TestMessageProcessor" );
51 51 assertNotNull( rubyProcessor );
2  modules/web/src/main/java/org/torquebox/web/rails/boot.rb
@@ -74,8 +74,6 @@ def load_gems
74 74 alias_method :initialize_before_torquebox!, :initialize!
75 75
76 76 def initialize!
77   - require 'torquebox-web'
78   -
79 77 self.class.initializer "monkeypatch-ar", :before=>'active_record.initialize_database', :after=>'active_record.set_configs' do
80 78 if ( defined?( ActiveRecord ) )
81 79 begin

No commit comments for this range

Something went wrong with that request. Please try again.