I've a strange problem.
I've install JbossAS 7.1.1 and deployed my ear file successfully.
My client is running to tomcat 6.035.
I can make successful EJB calls to my jboss deployment - but one specific EJB calls fails.
my client environment setup is as below :-
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,"org.jboss.naming.remote.client.InitialContextFactory");
env.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
env.put(Context.PROVIDER_URL, "remote://localhost:4447");
env.put(Context.SECURITY_PRINCIPAL, "abc");
env.put(Context.SECURITY_CREDENTIALS, "123");
env.put("jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false");
env.put("jboss.naming.client.ejb.context", "true");
env.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
env.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "false");
//env.put("remote.connection.x1.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "false");
logger.debug("Added security ");
try {
ctx = new InitialContext(env);
} catch (NamingException e) {
logger.error("Can't get initial context.");
e.printStackTrace();
}
The stracktrace is very strange. Its looking for RemoteNamingEJBClient
Please help - I'm out of idea.
18:03:25,541 WARN [org.jboss.modules] (EJB default - 8) Failed to define class org.jboss.naming.remote.client.ejb.RemoteNamingEjbClientContextSelector in Module "org.jboss.remote-naming:main" from local module loader #50988 (roots: jbossAS7/modules): java.lang.LinkageError: Failed to link org/jboss/naming/remote/client/ejb/RemoteNamingEjbClientContextSelector (Module "org.jboss.remote-naming:main" from local module loader #50988 (roots: jbossAS7/modules))
Caused by: java.lang.NoClassDefFoundError: org/jboss/ejb/client/ContextSelector
Caused by: java.lang.ClassNotFoundException: org.jboss.ejb.client.ContextSelector from [Module "org.jboss.remote-naming:main" from local module loader
I've solved this problem by adding
ejb-client module in remote-naming module
this issue is tracked here-
https://issues.jboss.org/browse/AS7-4872
<resources>
<resource-root path="jboss-remote-naming-1.0.2.Final.jar"/>
<!-- Insert resources here -->
</resources>
<dependencies>
<module name="javax.api"/>
<module name="org.jboss.ejb-client" />
<module name="org.jboss.remoting3"/>
<module name="org.jboss.logging"/>
<module name="org.jboss.marshalling"/>
<module name="org.jboss.marshalling.river"/>
</dependencies>
Related
This question already has answers here:
How to export swagger.json (or yaml)
(7 answers)
Closed 3 years ago.
I am using java spring boot framework to create REST api for my project and I am using "springfox-swagger2 and springfox-swagger-ui" for generating swagger documentation. I am able to see my documentation using the URL http://localhost:8080/swagger-ui.html.
How can I create or generate swagger.json / spec.json, The documentation should not be with this application, we are using a separate application for listing the API docs.
You can get the url with your swagger-ui html page:
GET http://localhost:8080/v2/api-docs?group=App
And actually you can get all the urls with chrome/firefox develop tools network feature.
If you use Maven, you can generate client and server side documentation (yaml, json and html) by using swagger-maven-plugin
Add this to your pom.xml:
.....
<plugin>
<groupId>com.github.kongchen</groupId>
<artifactId>swagger-maven-plugin</artifactId>
<version>3.0.1</version>
<configuration>
<apiSources>
<apiSource>
<springmvc>true</springmvc>
<locations>com.yourcontrollers.package.v1</locations>
<schemes>http,https</schemes>
<host>localhost:8080</host>
<basePath>/api-doc</basePath>
<info>
<title>Your API name</title>
<version>v1</version>
<description> description of your API</description>
<termsOfService>
http://www.yourterms.com
</termsOfService>
<contact>
<email>your-email#email.com</email>
<name>Your Name</name>
<url>http://www.contact-url.com</url>
</contact>
<license>
<url>http://www.licence-url.com</url>
<name>Commercial</name>
</license>
</info>
<!-- Support classpath or file absolute path here.
1) classpath e.g: "classpath:/markdown.hbs", "classpath:/templates/hello.html"
2) file e.g: "${basedir}/src/main/resources/markdown.hbs",
"${basedir}/src/main/resources/template/hello.html" -->
<templatePath>${basedir}/templates/strapdown.html.hbs</templatePath>
<outputPath>${basedir}/generated/document.html</outputPath>
<swaggerDirectory>generated/swagger-ui</swaggerDirectory>
<securityDefinitions>
<securityDefinition>
<name>basicAuth</name>
<type>basic</type>
</securityDefinition>
</securityDefinitions>
</apiSource>
</apiSources>
</configuration>
</plugin>
........
You can download *.hbs template at this address:
https://github.com/kongchen/swagger-maven-example
Execute mvn swagger:generate
JSon documentation will be generated at your project /generated/swagger/ directory.
Past it on this address :
http://editor.swagger.io
And generate what ever you want ( Server side or Client side API in your preferred technology )
I'm a little late here, but I just figured out that you can open your browser console and find the URL to the GET request that returns the JSON definition for your Swagger docs. The following technique worked for me when mapping my API to AWS API Gateway.
To do this:
Navigate to your Swagger docs endpoint
Open the browser console
Refresh the page
Navigate to the network tab and filter by XHR requests
Right click on the XHR request that ends in ?format=openapi
You can now just copy and paste that into a new JSON file!
I have done this with a small trick
I have added the following code in the end of my home controller test case
import org.springframework.boot.test.web.client.TestRestTemplate;
public class HomeControllerTest extends .... ...... {
#Autowired
private TestRestTemplate restTemplate;
#Test
public void testHome() throws Exception {
//.......
//... my home controller test code
//.....
String swagger = this.restTemplate.getForObject("/v2/api-docs", String.class);
this.writeFile("spec.json", swagger );
}
public void writeFile(String fileName, String content) {
File theDir = new File("swagger");
if (!theDir.exists()) {
try{
theDir.mkdir();
}
catch(SecurityException se){ }
}
BufferedWriter bw = null;
FileWriter fw = null;
try {
fw = new FileWriter("swagger/"+fileName);
bw = new BufferedWriter(fw);
bw.write(content);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bw != null)
bw.close();
if (fw != null)
fw.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
I don't know this is right way or not But it is working :)
Dependency
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
</dependency>
You should be able to get your swagger.json at
http://localhost:8080/api-docs
assuming your don't have kept the versioning as in the pet store sample application. In that case the URL would be:
http://localhost:8080/v2/api-docs
To get the api json definition for REST API, if swagger is configured properly. you can use directly swagger/docs/v1, this means the complete url will be, if version v1 (or just specify the version)
http://localhost:8080/swagger/docs/v1
I am trying to configure a Spring MVC Integration test using a combination of XML config and #Configuration annotated classes.
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#TestPropertySource({"/spring-security.properties",
"/rabbitmq-default.properties",
"/mongodb-default.properties",
"/webapp-override.properties"})
#ContextHierarchy({
#ContextConfiguration("classpath:**/security-config.xml"),
#ContextConfiguration(classes = RootConfig.class),
#ContextConfiguration(classes = SpringMvcConfig.class)
})
public class BaseConfiguredMvcIntegrationTest {
}
The java configurations are initialized correctly. The problem is although the "**/security-config.xml" file is found and parsed during initialization... all the spring security beans defined in there are never registered in the WebApplicationContext.
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1301)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1047)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
So my question is how do you utilize both XML based and annotated based configuration in a Spring MVC Integration test?
I could change the spring security config to java/annotated based one... I would rather not do this. I find using the spring security namespace more readable and concise than using the java config.
Also, note this combined XML/Java configuration works perfectly fine in a non-test environment.
Spring v4.1.6
Spring Security v4.0.1
WebApplicationContext Config:
package com.gggdw.web.config;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.DispatcherServlet;
#Configuration
public class GGGWebInitializer implements WebApplicationInitializer {
public static final String SERVLET_NAME = "ggg";
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
// Create the 'root' Spring application context
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(RootConfig.class);
// Manage the lifecycle of the root application context
servletContext.addListener(new ContextLoaderListener(rootContext));
// Create the dispatcher servlet's Spring application context
AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
dispatcherContext.register(SpringMvcConfig.class);
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher = servletContext.addServlet(SERVLET_NAME, new DispatcherServlet(dispatcherContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
//Spring security config
FilterRegistration.Dynamic springSecurityFilterChain = servletContext.addFilter(
"securityFilter", new DelegatingFilterProxy("springSecurityFilterChain"));
springSecurityFilterChain.addMappingForServletNames(null, false, SERVLET_NAME);
//springSecurityFilterChain.setAsyncSupported(true);
servletContext.addFilter("hiddenHttpMethodFilter", HiddenHttpMethodFilter.class);
}
}
RootConfig.class
#Configuration
#Import({WebPropertiesConfig.class, // loads all properties files on class path from resources folder
MongoConfig.class // init mongodb connection
})
#ImportResource({"classpath:**/security-config.xml"}) // spring security xml config (java config not as readable)
public class RootConfig {
}
security-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- <context:property-placeholder location="classpath:spring-security.properties" /> -->
<security:global-method-security pre-post-annotations="enabled" secured-annotations="enabled">
<security:expression-handler ref="expressionHandler"/>
</security:global-method-security>
<bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
<property name="permissionEvaluator" ref="permissionEvaluator"/>
</bean>
<bean id="permissionEvaluator"
class="com.my.local.package.security.GenericPermissionEvaluator">
</bean>
<!-- Configure Spring Security -->
<security:http auto-config="true" use-expressions="true" >
<security:form-login login-page="${spring.security.login-page}"
login-processing-url="${spring.security.login-processing-url}"
default-target-url="${spring.security.default-target-url}"
authentication-failure-url="${spring.security.authentication-failure-url}"
username-parameter="${spring.security.username-parameter}"
password-parameter="${spring.security.password-parameter}"
/>
<security:logout logout-url="${spring.security.logout-url}"
logout-success-url="${spring.security.logout-success-url}" />
<security:intercept-url pattern="/**" requires-channel="https" />
<security:intercept-url pattern="/s/**" access="isAuthenticated()" requires-channel="https" />
<security:custom-filter ref="log4JMDCFilter" after="SECURITY_CONTEXT_FILTER"/>
<security:access-denied-handler error-page="${spring.security.access-denied-handler-error-page}" />
<!-- <security:session-management invalid-session-url="${spring.security.invalid-session-url}"/>
2 types of invalid session, brand new user and a timeout of a previous logged in user
both need to be handled differently -->
</security:http>
<bean id="customUserDetailsService" class="com.my.local.package.CustomUserDetailsService" depends-on="userRepository"/>
<bean id="bCryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />
<!-- log4j filter to add userName and ipAddress into logging on a per request/thread basis -->
<bean id="log4JMDCFilter" class="com.my.local.package.filter.Log4JMDCFilter"/>
<security:authentication-manager>
<security:authentication-provider user-service-ref="customUserDetailsService">
<security:password-encoder ref="bCryptPasswordEncoder"/>
</security:authentication-provider>
</security:authentication-manager>
</beans>
UPDATE: upon further consideration and based on your latest feedback, the behavior you're experiencing might be the result of a bug that was introduced in Spring Framework 4.1.4 (see SPR-13075 for details).
Try downgrading to Spring Framework 4.1.3, and let me know if you still experience the undesired behavior.
note this combined XML/Java configuration works perfectly fine in a non-test environment.
How so?
Do you literally have three (3) contexts loaded in a hierarchy in production?
I doubt that. Rather, I assume you are somehow loading a single root WebApplicationContext from "classpath:**/security-config.xml" and RootConfig.class.
Thus, the most important question is: How are you configuring the root WebApplicationContext in production?
Once you have answered that, I can tell you how to achieve the same thing in your test configuration. ;)
Regards,
Sam (author of the Spring TestContext Framework)
Pay attention to the note from PathMatchingResourcePatternResolver:
Note that "classpath*:" when combined with Ant-style patterns will only work reliably with at least one root directory before the pattern starts, unless the actual target files reside in the file system. This means that a pattern like "classpath*:*.xml" will not retrieve files from the root of jar files but rather only from the root of expanded directories. This originates from a limitation in the JDK's ClassLoader.getResources() method which only returns file system locations for a passed-in empty String (indicating potential roots to search).
I've seen few similar issues on stackoverflow but i could not figure out how i can solve my problem. After adding Spring Security to my Spring MVC project i got following exception:
Jul 20, 2014 3:18:04 PM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
SEVERE: The web application [] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
Here is my mysql-connecter in the pom.xml
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.31</version>
</dependency>
Here are classes that i've added:
#Component
#Transactional
public class UserDetailsServiceImpl implements UserDetailsService{
#Autowired
private UserDAO userDAO;
#Autowired
private UserAssembler userAssembler;
private static final Logger logger = LoggerFactory.getLogger(UserDetailsServiceImpl.class);
#Transactional(readOnly = true)
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
User user = userDAO.findByEmail(username);
if(null == user) throw new UsernameNotFoundException("User not found");
return userAssembler.buildUserFromUser(user);
}
}
and assembler
#Service("assembler")
public class UserAssembler {
#Autowired
private UserDAO userDAO;
#Transactional(readOnly = true)
public User buildUserFromUser(net.viralpatel.contact.model.User user) {
String role = "ROLE_USER";//userEntityDAO.getRoleFromUserEntity(userEntity);
Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new GrantedAuthorityImpl(role));
return new User(user.getLogin(), user.getPassword(), true, true, true, true, authorities);
}
}
Here is my spring-security.xml
<beans:bean id="webexpressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler" />
<http auto-config="true">
<intercept-url pattern="/account/*" access="ROLE_ADMIN" />
<form-login login-page="/login" default-target-url="/account/overview" authentication-failure-url="/login?error=true"/>
<remember-me/>
</http>
<beans:bean id="myUserDetailsService" class="net.viralpatel.contact.service.UserDetailsServiceImpl" />
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="myUserDetailsService" />
</authentication-manager>
EDITED:
INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: /opt/idea-IU-135.909/bin::/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
Jul 20, 2014 3:58:36 PM org.apache.catalina.core.JreMemoryLeakPreventionListener lifecycleEvent
SEVERE: Failed to load class com.mysql.jdbc.NonRegisteringDriver during Tomcat start to prevent possible memory leaks.
java.lang.ClassNotFoundException: com.mysql.jdbc.NonRegisteringDriver
Your application doesn't have a flaw. It is the design of JDBC. The JDBC driver gets loaded and registered by the webapp when it creates a database connection for the first time.
That means that the driver is loaded with the web application class loader. On undeployment the driver doesn't get deregistered which in turn prevents your webapp classes from GC. That creates effectively a memory leak.
To prevent this particular memory leak you should edit your tomcat/conf/server.xml and change
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
to
<Listener
className="org.apache.catalina.core.JreMemoryLeakPreventionListener"
classesToInitialize="com.mysql.jdbc.NonRegisteringDriver" />
With mysql-connector-java-8.0.x use com.mysql.cj.jdbc.NonRegisteringDriver instead
Exclude the JDBC driver from your webapp artifact and put it into the tomcat/lib directory.
Now the JDBC driver gets loaded by Tomcat on startup and isn't linked to any webapps class loader.
Why should I modify the server.xml?
Another memory leaks manifests due to MySQL's 'Abandoned connection cleanup thread'. This thread starts with the first request and holds a reference to the webapp's classloader. With classesToInitialize you can prevent this memory leak too.
References:
org.apache.catalina.core.JreMemoryLeakPreventionListener tomcat-doc v7.0
AbandonedConnectionCleanupThread notes in v5.1.41
com.mysql.jdbc.NonRegisteringDriver source v5.1
com.mysql.cj.jdbc.NonRegisteringDriver source v8.0
mysql-connector-java changes in v8.0
What I did was just to put the mysql-connector-java-5.1.31-bin.jar in $CATALINA_HOME/lib. No modifications to server.xml.
I am trying to send email using thymeleaf template. But I am getting an error message as
org.thymeleaf.exceptions.TemplateProcessingException: Resource resolution by ServletContext with org.thymeleaf.resourceresolver.ServletContextResourceResolver can only be performed when context implements org.thymeleaf.context.IWebContext [current context: org.thymeleaf.context.Context]
at org.thymeleaf.resourceresolver.ServletContextResourceResolver.getResourceAsStream(ServletContextResourceResolver.java:74)
at org.thymeleaf.TemplateRepository.getTemplate(TemplateRepository.java:221)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1192)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1148)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1095)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1008)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:982)
at in.coep.vlabteam.leap.implementations.ScheduleNotificationImpl.sendNotification(ScheduleNotificationImpl.java:205)
at in.coep.vlabteam.leap.implementations.ScheduleNotificationImpl.sendScheduleNotificationMail(ScheduleNotificationImpl.java:105)
at in.coep.vlabteam.leap.services.ScheduleNotificationService.sendScheduleNotificationByMail(ScheduleNotificationService.java:47)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:64)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:53)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:206)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
10936 [taskScheduler-1] ERROR org.thymeleaf.TemplateEngine - [THYMELEAF][taskScheduler-1] Exception processing template "scheduleMail.html": Resource resolution by ServletContext with org.thymeleaf.resourceresolver.ServletContextResourceResolver can only be performed when context implements org.thymeleaf.context.IWebContext [current context: org.thymeleaf.context.Context]
I cant used WebContext() instead of Context(). Because for webContext I need HttpServletRequest object that I can't get here, because it is not in scope of request.
I am trying to send mail using context(), but I am getting an error.
Please anyone have solution on this. Thanks in advance
Here is my code,
final Context ctx = new Context();
ctx.setVariable("eagletId", user.getEagletId());
ctx.setVariable("name", user.getFirstName());
ctx.setVariable("setSentDate", new Date());
ctx.setVariable("department", user.getDepartment());
ctx.setVariable("batch", user.getBatch());
// ctx.setVariable("month" Constants.LeapConstants.UserType);
// Prepare message using a Spring helper
final MimeMessage mimeMessage = this.mailSender.createMimeMessage();
final MimeMessageHelper message =
new MimeMessageHelper(mimeMessage, true /* multipart */, "UTF-8");
message.setSubject("Create your report for month");
message.setFrom("leap#gmail.com");
message.setTo("vlab#gmail.com");
// Create the HTML body using Thymeleaf
final String htmlContent = this.templateEngine.process("scheduleMail.html", ctx);
message.setText(htmlContent, true /* isHtml */);
// Send mail
this.mailSender.send(mimeMessage);
Your template engine is configured with ServletContextTemplateResolver instead of either FileTemplateResolver or ClassLoaderTemplateResolver. This will be defined most likely in a spring config file somewhere. If configured in code, see the Thymeleaf user's guide on configuring the template engine and configuration of the templateResolver. It's good doc.
Via xml configuration, it should look something like this:
<beans:bean id="templateResolver"
class="org.thymeleaf.templateresolver.ClassLoaderTemplateResolver">
</beans:bean>
I am trying to bind my message driven bean with Oracle JCA file adapter (which is included in the SOA suite) on Weblogic 10.3.5. So that my MDB can get notified when there is any .txt file is moved to specific directory.
After launching a Weblogic domain with SOA features supported, the file adapter is automatically deployed. On Weblogic console I can see the file adapter is deployed as a "Resource Adapter", health is "OK", state is "Active", as shown below:
Also I run the tests of the file adapter, and they all passed:
So I think the file adapter is correctly deployed and should be functional.
Then my message driven bean code looks like this:
import java.util.logging.Logger;
import javax.ejb.MessageDriven;
import javax.resource.ResourceException;
import javax.resource.cci.MessageListener;
import javax.resource.cci.Record;
#MessageDriven
public class FileAdapterClientMDB implements MessageListener {
private Logger logger = Logger.getLogger(FileAdapterClientMDB.class.getName());
public FileAdapterClientMDB() {
}
#Override
public Record onMessage(Record record) throws ResourceException {
logger.info("Received record: " + record);
return record;
}
}
Here are the content of my ejb-jar.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:ejb="http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" version="3.0">
<display-name>MockEJB</display-name>
<enterprise-beans>
<message-driven>
<description>EMessage Driven Bean as File Adapter Client</description>
<display-name>FileAdapterClientMDB</display-name>
<ejb-name>FileAdapterClientMDB</ejb-name>
<ejb-class>com.test.FileAdapterClientMDB</ejb-class>
<messaging-type>javax.resource.cci.MessageListener</messaging-type>
<transaction-type>Container</transaction-type>
<activation-config>
<activation-config-property>
<activation-config-property-name>physicalDirectory</activation-config-property-name>
<activation-config-property-value>C:\dataDir</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>deleteFile</activation-config-property-name>
<activation-config-property-value>true</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>pollingFrequency</activation-config-property-name>
<activation-config-property-value>10</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>includeFiles</activation-config-property-name>
<activation-config-property-value>.*\.txt</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>minimumAge</activation-config-property-name>
<activation-config-property-value>0</activation-config-property-value>
</activation-config-property>
</activation-config>
</message-driven>
</enterprise-beans>
</ejb-jar>
And my weblogic-ejb-jar.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-ejb-jar xmlns:wls="http://www.bea.com/ns/weblogic/weblogic-ejb-jar" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd http://www.bea.com/ns/weblogic/weblogic-ejb-jar http://www.bea.com/ns/weblogic/weblogic-ejb-jar/1.0/weblogic-ejb-jar.xsd">
<!--weblogic-version:10.3-->
<wls:weblogic-enterprise-bean>
<!--options:RESOURCE_ADAPTER_JNDI-->
<wls:ejb-name>FileAdapterClientMDB</wls:ejb-name>
<wls:message-driven-descriptor>
<wls:resource-adapter-jndi-name>eis/FileAdapter</wls:resource-adapter-jndi-name>
</wls:message-driven-descriptor>
<wls:jndi-name>FileAdapterClientMDB</wls:jndi-name>
<wls:local-jndi-name>FileAdapterClientMDB</wls:local-jndi-name>
</wls:weblogic-enterprise-bean>
</wls:weblogic-ejb-jar>
While deploying the EAR project, I got this message:
<20.4.2012 22:42:11 CEST> <Warning> <EJB> <BEA-010221> <The Message-Driven EJB:
FileAdapterClientMDB is unable to bind to the JCA resource adapter: eis/FileAdapter.
The Error was: No deployed ResourceAdapter with adapter JNDI name = 'eis/FileAdapter' was found.>
I have no idea why Weblogic complain this, since the "eis/FileAdapter" JNDI name is mentioned in the official user guide of the adapter. Also I can see it in Weblogic's JNDI tree:
What's more, when I run the code below in my testing web service:
try {
final Context context = new InitialContext();
final Object obj = context.lookup("eis/FileAdapter");
System.out.println("eis/FileAdapter => " + obj);
} catch (NamingException e) {
e.printStackTrace();
}
It prints out "eis/FileAdapter => oracle.tip.adapter.file.FileConnectionFactory#ff51dc", which means the JNDI name is correct!
So my question is, why Weblogic could not find resource adapter with a "correct" JNDI name for binding? Could someone give me some ideas on how to solve it?
as long as you don't see this warning repeating you have nothing to worry. It just shows that in the order of deployment when the MDB was getting deployed it could not get the adapter. Note an MDB keeps trying to connect every 5 secs so if the warning continues to fill the log then that means the MDB has not been able to get the adapter meaning its not working, if you saw the warning only once you can safely ignore it or change the order of deployment and push the MDB little later.