torquebox-messaging 1.1.1-java → 2.0.0.beta1-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. data/lib/gem_hook.rb +26 -3
  2. data/lib/torquebox-messaging.jar +0 -0
  3. data/lib/torquebox-messaging.rb +2 -32
  4. data/lib/torquebox/messaging.rb +16 -0
  5. data/lib/torquebox/messaging/backgroundable.rb +32 -15
  6. data/lib/torquebox/messaging/backgroundable_processor.rb +32 -0
  7. data/lib/torquebox/messaging/connection.rb +127 -0
  8. data/lib/torquebox/messaging/connection_factory.rb +70 -0
  9. data/lib/torquebox/messaging/const_missing.rb +28 -0
  10. data/lib/torquebox/messaging/core.rb +27 -0
  11. data/lib/torquebox/messaging/destination.rb +68 -111
  12. data/lib/torquebox/messaging/ext/javax_jms_queue_browser.rb +1 -3
  13. data/lib/torquebox/messaging/future_responder.rb +10 -7
  14. data/lib/torquebox/messaging/json_message.rb +50 -0
  15. data/lib/torquebox/messaging/marshal_base64_message.rb +44 -0
  16. data/lib/torquebox/messaging/marshal_message.rb +43 -0
  17. data/lib/torquebox/messaging/message.rb +123 -0
  18. data/lib/torquebox/messaging/message_processor.rb +47 -0
  19. data/lib/torquebox/messaging/processor_wrapper.rb +38 -0
  20. data/lib/torquebox/messaging/queue.rb +61 -0
  21. data/lib/torquebox/messaging/session.rb +168 -0
  22. data/lib/torquebox/messaging/task.rb +7 -6
  23. data/lib/torquebox/messaging/text_message.rb +36 -0
  24. data/lib/torquebox/messaging/topic.rb +54 -0
  25. data/lib/torquebox/messaging/xa_connection.rb +58 -0
  26. data/lib/torquebox/messaging/xa_connection_factory.rb +59 -0
  27. data/lib/torquebox/messaging/xa_session.rb +30 -0
  28. data/licenses/lgpl-2.1.txt +7 -9
  29. data/spec/backgroundable_spec.rb +17 -24
  30. data/spec/destination_spec.rb +31 -318
  31. data/spec/future_responder_spec.rb +1 -1
  32. data/spec/json_message_spec.rb +50 -0
  33. data/spec/message_processor_spec.rb +54 -0
  34. data/spec/message_spec.rb +114 -0
  35. data/spec/task_spec.rb +11 -5
  36. metadata +38 -77
  37. data/lib/acl-spi-3.0.0.CR2.jar +0 -0
  38. data/lib/activation-1.1.jar +0 -0
  39. data/lib/authorization-spi-3.0.0.CR2.jar +0 -0
  40. data/lib/dtdparser-1.21.jar +0 -0
  41. data/lib/hornetq-core-2.1.2.Final.jar +0 -0
  42. data/lib/hornetq-jms-client-2.1.2.Final.jar +0 -0
  43. data/lib/hornetq-logging-2.1.2.Final.jar +0 -0
  44. data/lib/identity-spi-3.0.0.CR2.jar +0 -0
  45. data/lib/jaxb-api-2.1.9.jar +0 -0
  46. data/lib/jboss-common-core-2.2.17.GA.jar +0 -0
  47. data/lib/jboss-jms-api_1.1_spec-1.0.0.Final.jar +0 -0
  48. data/lib/jboss-logging-3.0.0.Beta4.jar +0 -0
  49. data/lib/jboss-reflect-2.2.0.GA.jar +0 -0
  50. data/lib/jbosssx-bare-3.0.0.CR2.jar +0 -0
  51. data/lib/jbossxacml-2.0.5.CR1.jar +0 -0
  52. data/lib/jbossxb-2.0.3.GA.jar +0 -0
  53. data/lib/jnp-client-5.0.5.Final.jar +0 -0
  54. data/lib/jruby-complete-1.6.3.jar +0 -0
  55. data/lib/netty-3.2.1.Final.jar +0 -0
  56. data/lib/picketbox-acl-impl-3.0.0.CR2.jar +0 -0
  57. data/lib/picketbox-bare-3.0.0.CR2.jar +0 -0
  58. data/lib/picketbox-identity-impl-3.0.0.CR2.jar +0 -0
  59. data/lib/picketbox-spi-bare-3.0.0.CR2.jar +0 -0
  60. data/lib/torquebox-base-core.jar +0 -0
  61. data/lib/torquebox-base-metadata.jar +0 -0
  62. data/lib/torquebox-base-spi.jar +0 -0
  63. data/lib/torquebox-mc-support.jar +0 -0
  64. data/lib/torquebox-messaging-core.jar +0 -0
  65. data/lib/torquebox/messaging/client.rb +0 -75
  66. data/lib/torquebox/messaging/ext/javax_jms_session.rb +0 -153
  67. data/lib/xercesImpl-2.9.1.jar +0 -0
  68. data/lib/xml-apis-1.3.04.jar +0 -0
  69. data/spec/client_spec.rb +0 -116
  70. data/spec/dispatcher-queues.yml +0 -4
  71. data/spec/dispatcher_not_running.rb +0 -54
  72. data/spec/ext/java_jmx_session_spec.rb +0 -71
  73. data/spec/queues.yml +0 -6
data/lib/gem_hook.rb CHANGED
@@ -15,9 +15,32 @@
15
15
  # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
16
16
  # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
17
17
 
18
- require 'torquebox/messaging/client'
19
- require 'torquebox/messaging/task'
18
+ begin
19
+ javax.jms::Session
20
+ rescue
21
+ # $stderr.puts "Will not load torquebox-messaging: javax.jms.* cannot be loaded"
22
+ return
23
+ end
24
+
25
+ require 'torquebox/messaging/connection_factory'
26
+ require 'torquebox/messaging/connection'
27
+ require 'torquebox/messaging/session'
28
+
29
+ require 'torquebox/messaging/message'
30
+ require 'torquebox/messaging/json_message'
31
+ require 'torquebox/messaging/text_message'
32
+ require 'torquebox/messaging/marshal_base64_message'
33
+ require 'torquebox/messaging/marshal_message'
34
+
20
35
  require 'torquebox/messaging/destination'
36
+ require 'torquebox/messaging/queue'
37
+ require 'torquebox/messaging/topic'
38
+
39
+ require 'torquebox/messaging/xa_connection_factory'
40
+ require 'torquebox/messaging/xa_connection'
41
+ require 'torquebox/messaging/xa_session'
42
+
21
43
  require 'torquebox/messaging/message_processor'
44
+ require 'torquebox/messaging/task'
22
45
  require 'torquebox/messaging/backgroundable'
23
- require 'torquebox/messaging/web_sockets_processor'
46
+ require 'torquebox/messaging/processor_wrapper'
Binary file
@@ -1,40 +1,10 @@
1
1
  module TorqueboxMessaging
2
- VERSION = '1.1.1'
3
- MAVEN_VERSION = '1.1.1'
2
+ VERSION = '2.0.0.beta1'
3
+ MAVEN_VERSION = '2.0.0.beta1'
4
4
  end
5
5
  begin
6
6
  require 'java'
7
7
  require File.dirname(__FILE__) + '/torquebox-messaging.jar'
8
- require File.dirname(__FILE__) + '/jboss-jms-api_1.1_spec-1.0.0.Final.jar'
9
- require File.dirname(__FILE__) + '/hornetq-core-2.1.2.Final.jar'
10
- require File.dirname(__FILE__) + '/hornetq-jms-client-2.1.2.Final.jar'
11
- require File.dirname(__FILE__) + '/netty-3.2.1.Final.jar'
12
- require File.dirname(__FILE__) + '/hornetq-logging-2.1.2.Final.jar'
13
- require File.dirname(__FILE__) + '/jboss-logging-3.0.0.Beta4.jar'
14
- require File.dirname(__FILE__) + '/jnp-client-5.0.5.Final.jar'
15
- require File.dirname(__FILE__) + '/jboss-common-core-2.2.17.GA.jar'
16
- require File.dirname(__FILE__) + '/jboss-reflect-2.2.0.GA.jar'
17
- require File.dirname(__FILE__) + '/jbossxb-2.0.3.GA.jar'
18
- require File.dirname(__FILE__) + '/xml-apis-1.3.04.jar'
19
- require File.dirname(__FILE__) + '/xercesImpl-2.9.1.jar'
20
- require File.dirname(__FILE__) + '/dtdparser-1.21.jar'
21
- require File.dirname(__FILE__) + '/activation-1.1.jar'
22
- require File.dirname(__FILE__) + '/jaxb-api-2.1.9.jar'
23
- require File.dirname(__FILE__) + '/torquebox-base-spi.jar'
24
- require File.dirname(__FILE__) + '/jruby-complete-1.6.3.jar'
25
- require File.dirname(__FILE__) + '/torquebox-base-metadata.jar'
26
- require File.dirname(__FILE__) + '/torquebox-base-core.jar'
27
- require File.dirname(__FILE__) + '/picketbox-bare-3.0.0.CR2.jar'
28
- require File.dirname(__FILE__) + '/identity-spi-3.0.0.CR2.jar'
29
- require File.dirname(__FILE__) + '/authorization-spi-3.0.0.CR2.jar'
30
- require File.dirname(__FILE__) + '/acl-spi-3.0.0.CR2.jar'
31
- require File.dirname(__FILE__) + '/jbosssx-bare-3.0.0.CR2.jar'
32
- require File.dirname(__FILE__) + '/picketbox-identity-impl-3.0.0.CR2.jar'
33
- require File.dirname(__FILE__) + '/picketbox-spi-bare-3.0.0.CR2.jar'
34
- require File.dirname(__FILE__) + '/picketbox-acl-impl-3.0.0.CR2.jar'
35
- require File.dirname(__FILE__) + '/jbossxacml-2.0.5.CR1.jar'
36
- require File.dirname(__FILE__) + '/torquebox-mc-support.jar'
37
- require File.dirname(__FILE__) + '/torquebox-messaging-core.jar'
38
8
  rescue LoadError
39
9
  puts 'JAR-based gems require JRuby to load. Please visit www.jruby.org.'
40
10
  raise
@@ -1,3 +1,19 @@
1
+ # Copyright 2008-2011 Red Hat, Inc, and individual contributors.
2
+ #
3
+ # This is free software; you can redistribute it and/or modify it
4
+ # under the terms of the GNU Lesser General Public License as
5
+ # published by the Free Software Foundation; either version 2.1 of
6
+ # the License, or (at your option) any later version.
7
+ #
8
+ # This software is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ # Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public
14
+ # License along with this software; if not, write to the Free
15
+ # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
16
+ # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
1
17
 
2
18
  begin
3
19
  require 'torquebox-messaging'
@@ -1,38 +1,53 @@
1
1
  # Copyright 2008-2011 Red Hat, Inc, and individual contributors.
2
- #
2
+ #
3
3
  # This is free software; you can redistribute it and/or modify it
4
4
  # under the terms of the GNU Lesser General Public License as
5
5
  # published by the Free Software Foundation; either version 2.1 of
6
6
  # the License, or (at your option) any later version.
7
- #
7
+ #
8
8
  # This software is distributed in the hope that it will be useful,
9
9
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
11
  # Lesser General Public License for more details.
12
- #
12
+ #
13
13
  # You should have received a copy of the GNU Lesser General Public
14
14
  # License along with this software; if not, write to the Free
15
15
  # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
16
16
  # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
17
17
 
18
- require 'torquebox/messaging/destination'
18
+ require 'torquebox/messaging/queue'
19
19
  require 'torquebox/messaging/future'
20
+ require 'torquebox/messaging/task'
20
21
  require 'torquebox/messaging/future_status'
22
+ require 'torquebox/injectors'
21
23
 
22
24
  module TorqueBox
23
25
  module Messaging
26
+
27
+ # Backgroundable provides mechanism for executing an object's
28
+ # methods asynchronously.
24
29
  module Backgroundable
25
30
  def self.included(base)
26
31
  base.extend(ClassMethods)
27
32
  base.send(:include, FutureStatus)
28
33
  end
29
34
 
35
+ # Allows you to background any method that has not been marked
36
+ # as a backgrounded method via {ClassMethods#always_background}.
37
+ # @param [Hash] options that are passed through to
38
+ # {TorqueBox::Messaging::Destination#publish}
39
+ # @return [Future]
30
40
  def background(options = { })
31
41
  BackgroundProxy.new(self, options)
32
42
  end
33
43
 
34
44
  module ClassMethods
35
45
 
46
+ # Marks methods to always be backgrounded. Takes one or more
47
+ # method symbols, and an optional options hash as the final
48
+ # argument. The options allow you to set publish options for
49
+ # each call.
50
+ # see TorqueBox::Messaging::Destination#publish
36
51
  def always_background(*methods)
37
52
  options = methods.last.is_a?(Hash) ? methods.pop : {}
38
53
  @__backgroundable_methods ||= {}
@@ -103,21 +118,23 @@ module TorqueBox
103
118
  end
104
119
 
105
120
  module Util
106
- QUEUE_NAME = "/queues/torquebox/#{ENV['TORQUEBOX_APP_NAME']}/backgroundable"
107
-
121
+ extend TorqueBox::Injectors
122
+
108
123
  class << self
109
124
  def publish_message(receiver, method, args, options = { })
110
- queue = Queue.new(QUEUE_NAME)
125
+ queue_name = Task.queue_name( "torquebox_backgroundable" )
126
+ queue = Queue.new( queue_name )
111
127
  future = Future.new( queue )
112
- queue.publish({:receiver => receiver,
113
- :future_id => future.correlation_id,
114
- :future_queue => QUEUE_NAME,
115
- :method => method,
116
- :args => args}, options)
117
-
128
+ options[:encoding] = :marshal
129
+ queue.publish( {:receiver => receiver,
130
+ :future_id => future.correlation_id,
131
+ :future_queue => queue_name,
132
+ :method => method,
133
+ :args => args}, options )
134
+
118
135
  future
119
- rescue javax.naming.NameNotFoundException => ex
120
- raise RuntimeError.new("The backgroundable queue is not available. Did you disable it by setting its concurrency to 0?")
136
+ rescue javax.jms.InvalidDestinationException => ex
137
+ raise RuntimeError.new("The Backgroundable queue is not available. Did you disable it by setting its concurrency to 0?")
121
138
  end
122
139
 
123
140
  def instance_methods_include?(klass, method)
@@ -0,0 +1,32 @@
1
+ # Copyright 2008-2011 Red Hat, Inc, and individual contributors.
2
+ #
3
+ # This is free software; you can redistribute it and/or modify it
4
+ # under the terms of the GNU Lesser General Public License as
5
+ # published by the Free Software Foundation; either version 2.1 of
6
+ # the License, or (at your option) any later version.
7
+ #
8
+ # This software is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ # Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public
14
+ # License along with this software; if not, write to the Free
15
+ # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
16
+ # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
17
+
18
+ require 'torquebox/messaging/message_processor'
19
+ require 'torquebox/messaging/const_missing'
20
+ require 'torquebox/messaging/future_responder'
21
+
22
+ module TorqueBox
23
+ module Messaging
24
+ class BackgroundableProcessor < MessageProcessor
25
+ def on_message(hash)
26
+ FutureResponder.new( Queue.new( hash[:future_queue] ), hash[:future_id] ).respond do
27
+ hash[:receiver].send(hash[:method], *hash[:args])
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,127 @@
1
+ # Copyright 2008-2011 Red Hat, Inc, and individual contributors.
2
+ #
3
+ # This is free software; you can redistribute it and/or modify it
4
+ # under the terms of the GNU Lesser General Public License as
5
+ # published by the Free Software Foundation; either version 2.1 of
6
+ # the License, or (at your option) any later version.
7
+ #
8
+ # This software is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ # Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public
14
+ # License along with this software; if not, write to the Free
15
+ # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
16
+ # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
17
+
18
+ require 'torquebox/injectors'
19
+ require 'torquebox/messaging/session'
20
+
21
+ module TorqueBox
22
+ module Messaging
23
+ class Connection
24
+ include TorqueBox::Injectors
25
+
26
+ def initialize(jms_connection)
27
+ @jms_connection = jms_connection
28
+ @tm = inject('transaction-manager')
29
+ end
30
+
31
+ def start
32
+ @jms_connection.start
33
+ end
34
+
35
+ def close
36
+ @jms_connection.close
37
+ end
38
+
39
+ def client_id
40
+ @jms_connection.client_id
41
+ end
42
+
43
+ def client_id=(client_id)
44
+ @jms_connection.client_id = client_id
45
+ end
46
+
47
+ def with_session(enlist_tx = true)
48
+ if !enlist_tx || (current.nil? && !transaction)
49
+ begin
50
+ yield activate( create_session )
51
+ ensure
52
+ deactivate
53
+ end
54
+ elsif transaction && (!current.respond_to?(:transaction) || current.transaction != transaction)
55
+ yield activate( create_xa_session )
56
+ else
57
+ yield( current )
58
+ end
59
+ end
60
+
61
+ def sessions
62
+ Thread.current[:session] ||= []
63
+ end
64
+ def current
65
+ sessions.last
66
+ end
67
+ def activate(session)
68
+ sessions.push(session) && current
69
+ end
70
+ def deactivate
71
+ sessions.pop.close
72
+ end
73
+
74
+ def transaction
75
+ @tm && @tm.transaction
76
+ end
77
+
78
+ def create_xa_session
79
+ jms_session = @jms_connection.create_xa_session()
80
+ transaction.enlist_resource( jms_session.xa_resource )
81
+ session = TransactedSession.new( jms_session, transaction, self )
82
+ transaction.registerSynchronization( session )
83
+ session
84
+ end
85
+
86
+ def create_session
87
+ Session.new( @jms_connection.create_session( false, Session::AUTO_ACK ) )
88
+ end
89
+
90
+ end
91
+
92
+ class TransactedSession < Session
93
+ include javax.transaction.Synchronization
94
+ attr_reader :transaction
95
+
96
+ def initialize( jms_session, transaction, connection )
97
+ super( jms_session )
98
+ @transaction = transaction
99
+ @connection = connection.extend(TransactedConnection)
100
+ end
101
+
102
+ def close
103
+ # eat the close, until tx completes
104
+ end
105
+
106
+ def beforeCompletion
107
+ # required interface
108
+ end
109
+
110
+ def afterCompletion(status)
111
+ @connection.deactivate
112
+ @connection.complete!
113
+ end
114
+ end
115
+
116
+ module TransactedConnection
117
+ def close
118
+ super if @complete
119
+ end
120
+ def complete!
121
+ @complete = true
122
+ close
123
+ end
124
+ end
125
+
126
+ end
127
+ end
@@ -0,0 +1,70 @@
1
+ # Copyright 2008-2011 Red Hat, Inc, and individual contributors.
2
+ #
3
+ # This is free software; you can redistribute it and/or modify it
4
+ # under the terms of the GNU Lesser General Public License as
5
+ # published by the Free Software Foundation; either version 2.1 of
6
+ # the License, or (at your option) any later version.
7
+ #
8
+ # This software is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ # Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public
14
+ # License along with this software; if not, write to the Free
15
+ # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
16
+ # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
17
+
18
+ require 'java'
19
+ require 'torquebox/messaging/connection'
20
+
21
+ module TorqueBox
22
+ module Messaging
23
+ class ConnectionFactory
24
+
25
+ attr_reader :internal_connection_factory
26
+
27
+ def self.new(internal_connection_factory = nil)
28
+ return internal_connection_factory if internal_connection_factory.is_a?( ConnectionFactory )
29
+ super
30
+ end
31
+
32
+ def initialize(internal_connection_factory = nil)
33
+ @internal_connection_factory = internal_connection_factory
34
+ end
35
+
36
+ def with_new_connection(client_id = nil, &block)
37
+ connection = create_connection
38
+ connection.client_id = client_id
39
+ connection.start
40
+ begin
41
+ result = block.call( connection )
42
+ ensure
43
+ connection.close
44
+ end
45
+ return result
46
+ end
47
+
48
+ def create_connection()
49
+ if !@internal_connection_factory
50
+ # try to connect to HornetQ directly - this currently
51
+ # assumes localhost, and the default AS7 HQ Netty port of 5445
52
+ connect_opts = { org.hornetq.core.remoting.impl.netty.TransportConstants::PORT_PROP_NAME => 5445.to_java( java.lang.Integer ) }
53
+ transport_config =
54
+ org.hornetq.api.core.TransportConfiguration.new("org.hornetq.core.remoting.impl.netty.NettyConnectorFactory",
55
+ connect_opts)
56
+ @internal_connection_factory =
57
+ org.hornetq.api.jms.HornetQJMSClient.createConnectionFactoryWithoutHA( org.hornetq.api.jms::JMSFactoryType::CF, transport_config )
58
+ end
59
+
60
+ Connection.new( @internal_connection_factory.create_connection )
61
+ end
62
+
63
+
64
+ def to_s
65
+ "[ConnectionFactory: internal_connection_factory=#{internal_connection_factory}]"
66
+ end
67
+
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,28 @@
1
+ # Copyright 2008-2011 Red Hat, Inc, and individual contributors.
2
+ #
3
+ # This is free software; you can redistribute it and/or modify it
4
+ # under the terms of the GNU Lesser General Public License as
5
+ # published by the Free Software Foundation; either version 2.1 of
6
+ # the License, or (at your option) any later version.
7
+ #
8
+ # This software is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ # Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public
14
+ # License along with this software; if not, write to the Free
15
+ # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
16
+ # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
17
+
18
+ unless defined?(ActiveSupport)
19
+ $stderr.puts "WARN: Defining const_missing"
20
+
21
+ def Object.const_missing(name)
22
+ file = org.torquebox.core.util.StringUtils.underscore(name)
23
+ require file
24
+ result = const_get(name)
25
+ return result if result
26
+ raise "Class not found: #{name}"
27
+ end
28
+ end