Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JMS: XA-only ConnectionFactory created for ActiveMQ Artemis #1284

Closed
jensdt opened this issue Mar 25, 2019 · 23 comments
Closed

JMS: XA-only ConnectionFactory created for ActiveMQ Artemis #1284

jensdt opened this issue Mar 25, 2019 · 23 comments

Comments

@jensdt
Copy link

jensdt commented Mar 25, 2019

When using ActiveMQ Artemis through JMS over remote JNDI, the connection factory we get back is an instance of org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory. But as per https://activemq.apache.org/artemis/docs/javadocs/javadoc-2.6.0/org/apache/activemq/artemis/jms/client/ActiveMQJMSConnectionFactory.html, you see this implements both javax.jms.ConnectionFactory and javax.jms.XAConnectionFactory. We want to use it in a non-XA fashion (we don't need XA transactions in our use case), but because of this check we get a XA-only ConnectionFactory back after instrumentation with Brave.

IMHO this PostProcessor should be extended to create a bean that is also both an XA and non-XA connection factory if the instrumented bean is also both. If you agree this is a bug I'm open to fixing this myself with a PR - just let me know.

@bvoss
Copy link

bvoss commented Apr 3, 2019

a big
+1
from my side.

It's very confusing to end up with an application startup failure by just adding the sleuth dependency with an error message regarding unsatisfied bean dependency.

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jmsTemplate' defined in class path resource [JmsConfig.class]: Unsatisfied dependency expressed through method 'jmsTemplate' parameter 0; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'devConnectionFactory' is expected to be of type 'javax.jms.ConnectionFactory' but was actually of type 'org.springframework.cloud.sleuth.instrument.messaging.LazyXAConnectionFactory

but in the config you declare a bean of the correct type:

   @Bean("jmsConnectionFactory")
   public ConnectionFactory devConnectionFactory() {
        ConnectionFactory factory =  new ActiveMQJMSConnectionFactory(brokerURL, userName, password);
        LOGGER.info("Starting Artemis JMS connection to {}", brokerURL);
        return factory;
    }

@marcingrzejszczak marcingrzejszczak added this to To do in Hoxton.M1 via automation Apr 8, 2019
@marcingrzejszczak marcingrzejszczak added this to the 2.2.0.M1 milestone Apr 8, 2019
@marcingrzejszczak
Copy link
Contributor

Should be fixed via 1b493e6 . Please check out the latest snapshots.

Hoxton.M1 automation moved this from To do to Done Apr 8, 2019
@jensdt
Copy link
Author

jensdt commented Apr 8, 2019

I tested this with the latest 2.2.0.BUILD-SNAPSHOT, but still have the same issue. I also don't really see from the code change how this would be fixed. A bean that is both a javax.jms.ConnectionFactory and javax.jms.XAConnectionFactory will still be wrapped in a LazyXAConnectionFactory which is not a javax.jms.ConnectionFactory anymore.

Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'jmsConnectionFactory' is expected to be of type 'javax.jms.ConnectionFactory' but was actually of type 'org.springframework.cloud.sleuth.instrument.messaging.LazyXAConnectionFactory'

You did fix 1324, but only if the bean isn't also an XAConnectionFactory. Else the error will remain for the same reason.

@marcingrzejszczak
Copy link
Contributor

Ah true, thanks for pointing it out

Hoxton.M1 automation moved this from Done to In progress Apr 8, 2019
Hoxton.M1 automation moved this from In progress to Done Apr 11, 2019
@nick250386
Copy link

nick250386 commented Jul 1, 2019

When using Sleuth for an application using AWS SQS messaging, I am getting an error, given below:

Caused by: java.lang.IllegalStateException: **@Bean method JmsConfig.defaultConnectionFactory called as bean reference for type [com.amazon.sqs.javamessaging.SQSConnectionFactory] but overridden by non-compatible bean instance of type** [org.springframework.cloud.sleuth.instrument.messaging.LazyConnectionFactory]. Overriding bean of same name declared in: class path resource [c/z/o/a/s/JmsConfig.class]
	at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.resolveBeanReference(ConfigurationClassEnhancer.java:418) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:366) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at c.z.o.a.s.JmsConfig$$EnhancerBySpringCGLIB$$8e92a374.defaultConnectionFactory(<generated>) ~[classes/:na]
	at c.z.o.a.s.JmsConfig.defaultJmsTemplate(JmsConfig.java:58) ~[classes/:na]
	at c.z.o.a.s.JmsConfig$$EnhancerBySpringCGLIB$$8e92a374.CGLIB$defaultJmsTemplate$2(<generated>) ~[classes/:na]
	at c.z.o.a.s.JmsConfig$$EnhancerBySpringCGLIB$$8e92a374$$FastClassBySpringCGLIB$$4ad44584.invoke(<generated>) ~[classes/:na]
	at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at c.z.o.a.s.JmsConfig$$EnhancerBySpringCGLIB$$8e92a374.defaultJmsTemplate(<generated>) ~[classes/:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_202]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_202]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_202]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_202]
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	... 76 common frames omitted

Does this mean that as per the commit here, the library need to support AWS SQSConnectionFactory ?

Any pointers if I am missing something here ?

@marcingrzejszczak
Copy link
Contributor

Please learn how to properly format the code. Can you also provide which version of Sleuth you're using?

@nick250386
Copy link

My bad, I was trying to insert it properly using the '<>' control but seems like I made a mistake there. (I will try to rectify that.)Currently I am facing this issue with Sleuth version '2.1.0.RELEASE'

@marcingrzejszczak
Copy link
Contributor

It's not the latest GA version of Sleuth available. Please upgrade to the latest and see if the problem persists.

@nick250386
Copy link

The Maven repository has dependency defined for '2.1.2.RELEASE' while the latest version of this library is '2.2.0'. Do you think it will work for '2.1.2.RELEASE' ?

@marcingrzejszczak
Copy link
Contributor

Please test 2.1.2.RELEASE. Typically before interacting with a closed issue you should verify whether the latest version works fine.

@nick250386
Copy link

Apologies if I deviated from the process.
Actually, I was able to get things running fine with the integration with the '2.1.0.RELEASE' version. I ran into issues when I ran JUnit test cases on it and it is then I got the above error I mentioned. I was not sure if I should have opened a new issue seeking support on this and I found this one relevant to my use case.

@nick250386
Copy link

UPDATE: With version '2.1.2.RELEASE' I continue to get the same error.

@marcingrzejszczak
Copy link
Contributor

Can you provide a complete, minimal, verifiable sample that reproduces the problem rather than pasted code? It should be available as a GitHub (or similar) project or attached to this issue as a zip file.

@nick250386
Copy link

nick250386 commented Jul 1, 2019

Providing a sample would be difficult, but is there anything or any information that you are specifically looking for, that I can provide.
My project has a bunch of microservices, and integration with Sleuth is working fine even with the older version i.e. '2.1.0.RELEASE' but I am facing issues with a micro-service module that uses AWS SQS service. I was able to deduce this as the only reason based on the error log that I provided.

@nick250386
Copy link

I managed to create a sample spring boot application throwing the same error as I am encountering in my project. Along with it, I am also attaching the stacktrace of the exception that I am getting. Let me know if this helps.
Error_Stacktrace.txt
demo.zip

Hoxton.M1 automation moved this from Done to In progress Jul 2, 2019
@nick250386
Copy link

@marcingrzejszczak , do you think the issue I reported is a valid one or there is something wrong at my end. If possible, can you please share the proposed plan on this issue if it's a valid one ?

@marcingrzejszczak
Copy link
Contributor

I'm sorry but I didn't have time to look into it but by the looks of it some code in your codebase is requiring a direct SQSConnectionFactory type. We're wrapping it in a tracing representation. That means that if you try to inject the SQSConnectionFactory you'll fail. If that's your code, can you use an interface instead of the concrete implementation?

@nick250386
Copy link

Can you help me in understanding how this wrapping works and what are you suggesting me to do ?

@spencergibb spencergibb added this to To do in Hoxton.M2 via automation Jul 3, 2019
@spencergibb spencergibb removed this from In progress in Hoxton.M1 Jul 3, 2019
@spencergibb spencergibb removed this from the 2.2.0.M1 milestone Jul 3, 2019
@codefromthecrypt
Copy link
Contributor

codefromthecrypt commented Jul 3, 2019 via email

@nick250386
Copy link

@marcingrzejszczak / @adriancole , I gave a few attempts along the lines of your suggestions of using an interface to inject SQSConnectionFactory instead of a concrete implementation, but it seems like I am not getting the idea of how to do it. If possible, can give an example on how to achieve this based on the sample project that I provided.

@nick250386
Copy link

Apologies for delayed response.
I was able to solve the issue following the inputs given by @marcingrzejszczak & @adriancole .
Instead of having a concrete return type of the method as 'SQSConnectionFactory', even though I continued to return an instance of 'SQSConnectionFactory' I changed the method signature to return 'ConnectionFactory'.

EARLIER:

public SQSConnectionFactory defaultConnectionFactory() {
		return new SQSConnectionFactory(new ProviderConfiguration(), AmazonSQSClientBuilder.standard().withRegion(Regions.fromName(awsRegion))
				.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey))));
	}

LATER:

public ConnectionFactory defaultConnectionFactory() {
		return new SQSConnectionFactory(new ProviderConfiguration(), AmazonSQSClientBuilder.standard().withRegion(Regions.fromName(awsRegion))
				.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey))));
	}

Please let me know if this is right or I should have tried something else.

@marcingrzejszczak
Copy link
Contributor

Exactly, that's what we suggested! Thanks for typing it down in the answer. We really appreciate it!

Hoxton.M2 automation moved this from To do to Done Jul 18, 2019
@codefromthecrypt
Copy link
Contributor

codefromthecrypt commented Jul 19, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Hoxton.M2
  
Done
Development

No branches or pull requests

8 participants