View | Details | Raw Unified | Return to bug 47290
Collapse All | Expand All

(-)src/protocol/jms/org/apache/jmeter/protocol/jms/client/ConnectionFactory.java (-6 / +80 lines)
Lines 44-49 Link Here
44
    private static final Logger log = LoggingManager.getLoggerForClass();
44
    private static final Logger log = LoggingManager.getLoggerForClass();
45
    /**
46
     * Maximum number of times we will attempt to obtain a connection factory.
47
     */
48
    private static final int MAX_RETRY = 50;
49
50
    /**
51
     * Amount of time to pause between connection factory lookup attempts.
52
     */
53
    private static final int PAUSE_MILLIS = 100;
54
45
    //@GuardedBy("this")
55
    //@GuardedBy("this")
46
    private static TopicConnectionFactory factory = null;
56
    private static TopicConnectionFactory factory = null;
Lines 85-113 Link Here
85
    public void testIterationStart(LoopIterationEvent event) {
95
    public void testIterationStart(LoopIterationEvent event) {
86
    }
96
    }
87
    public static synchronized TopicConnectionFactory getTopicConnectionFactory(Context ctx, String fac) {
97
    /**
88
        while (factory == null) {
98
     * Gets the topic connection factory. Looks it up in JNDI if necessary.
99
     * <p>
100
     * The original code looped indefinitely until the connection factory was
101
     * found. Unfortunately, whoever wrote the code left no clue as to why the
102
     * code looped indefinitely. Perhaps, for the messaging system used by the
103
     * coder, there was the possibility of some time delay, so that the factory
104
     * might not be available on the first lookup, but would be available later.
105
     * Note that I am giving the initial coder the benefit of the doubt, and
106
     * am assuming there was a legitimate reason for the infinite loop.
107
     * </p><p>
108
     * However, the indefinite lookup has problems. Consider if the JMeter user
109
     * provided incorrect JNDI information, such as the jndi.properties file
110
     * was not added to user.classpath, or the factory name was misspelled. The
111
     * result is an infinite loop that generates bucket-loads of logging. Ask me
112
     * how I know this - I got a 1GB log file in a little over a minute.
113
     * </p><p>
114
     * Asuming there was a reason to try the lookup more than once I changed the
115
     * code to:
116
     * </p><ul>
117
     * <li>Wait 100 milliseconds between lookups</li>
118
     * <li>Loop only 50 times (5 seconds) before giving up (this was a wild
119
     * guess, because like I said the original coder left no clues as to why
120
     * there was a loop here)</li>
121
     * <li>Only log an error on the first and last time through the loop,
122
     * uniquely identifying each entry</li>
123
     * </ul><p>
124
     * That presented another issue - what to do if the lookup failed. This
125
     * method is called from two locations, both of which are in a try/catch
126
     * block, with JMSException being caught. Therefore I imagined that the best
127
     * solution, which involved the fewest changes, would be to throw a
128
     * JMSException. Unfortunately, in my testing the tester threads hung. But
129
     * if I let this method return null, the testing threads did not hang.
130
     * Rather that trying to determine why throwing a JMSException causes the
131
     * testing threads to hang, and thus expanding the scope of this patch I
132
     * decided to just return null.
133
     */
134
    public static synchronized TopicConnectionFactory getTopicConnectionFactory(Context ctx, String fac) {
135
        int counter = MAX_RETRY;
136
        while (factory == null && counter > 0) {
89
            try {
137
            try {
90
                Object objfac = ctx.lookup(fac);
138
                Object objfac = ctx.lookup(fac);
91
                if (objfac instanceof TopicConnectionFactory) {
139
                if (objfac instanceof TopicConnectionFactory) {
92
                    factory = (TopicConnectionFactory) objfac;
140
                    factory = (TopicConnectionFactory) objfac;
93
                }
141
                }
94
            } catch (NamingException e) {
142
            } catch (NamingException e) {
95
                log.error(e.toString());
143
                if (counter == MAX_RETRY) {
144
                    log.error("Unable to find connection factory " + fac + ", will retry. Error: " + e.toString());
145
                } else if (counter == 1) {
146
                    log.error("Unable to find connection factory " + fac + ", giving up. Error: " + e.toString());
147
                }
148
                counter--;
149
                try {
150
                    Thread.currentThread().sleep(PAUSE_MILLIS);
151
                } catch (InterruptedException ie) {
152
                    // do nothing, getting interrupted is acceptable
153
                }
96
            }
154
            }
97
        }
155
        }
98
        return factory;
156
        return factory;
99
    }
157
    }
100
    public static synchronized QueueConnectionFactory getQueueConnectionFactory(Context ctx, String fac) {
158
    /**
101
        while (qfactory == null) {
159
     * Gets the topic connection factory. Looks it up in JNDI if necessary.
160
     * </p><p>
161
     * See getTopicConnectionFactory for design details.
162
     */
163
    public static synchronized QueueConnectionFactory getQueueConnectionFactory(Context ctx, String fac) {
164
        int counter = MAX_RETRY;
165
        while (qfactory == null && counter > 0) {
102
            try {
166
            try {
103
                Object objfac = ctx.lookup(fac);
167
                Object objfac = ctx.lookup(fac);
104
                if (objfac instanceof QueueConnectionFactory) {
168
                if (objfac instanceof QueueConnectionFactory) {
105
                    qfactory = (QueueConnectionFactory) objfac;
169
                    qfactory = (QueueConnectionFactory) objfac;
106
                }
170
                }
107
            } catch (NamingException e) {
171
            } catch (NamingException e) {
108
                log.error(e.getMessage());
172
                if (counter == MAX_RETRY) {
173
                    log.error("Unable to find connection factory " + fac + ", will retry. Error: " + e.toString());
174
                } else if (counter == 1) {
175
                    log.error("Unable to find connection factory " + fac + ", giving up. Error: " + e.toString());
176
                }
177
                counter--;
178
                try {
179
                    Thread.currentThread().sleep(PAUSE_MILLIS);
180
                } catch (InterruptedException ie) {
181
                  // do nothing, getting interrupted is acceptable
182
                }
109
            }
183
            }
110
        }
184
        }
111
        return qfactory;
185
        return qfactory;

Return to bug 47290