Error: Multiple RestConsumerFactory found on classpath - java

Getting error while calling addRouteDefinition. I am dynamically adding rest to camelcontext.
Error
org.apache.camel.FailedToCreateRouteException : Failed to create route ... because of Multiple RestConsumerFactory found on classpath. Configure explicit which component to use
RestsDefinition rests = camelContext.loadRestsDefinition(is);
camelContext.addRestDefinitions(rests.getRests());
for (RestDefinition restDefinition : rests.getRests()) {
List<RouteDefinition> routeDefinitions = restDefinition.asRouteDefinition(camelContext);
System.out.println(routeDefinitions);
//camelContext.addRouteDefinitions(routeDefinitions);
for (RouteDefinition route1 : routeDefinitions) {
System.out.println("Route being Added : " + route1.getId());
//Getting Error in this line
camelContext.addRouteDefinition(route1);
}
}
Can anyone help me with this.
Thank you.

The problem was with RestConfiguration as the RestConfiguration was not set correctly on camelcontext so added. camelContext.addRestConfiguration(restConfiguration);

Related

How to read data from META/MANIFEST.MF in Spring Boot MVC Web Application?

I have a requirement to read information that is available in the META/MANIFEST.MF file of Spring Boot MVC web application and use this info to perform some business logic. I'm using gradle to build the application as war file and deploying it into the external tomcat.
I have tried the following:
#Configuration
public class AppConfig
{
#Bean("manifest")
public java.util.jar.Manifest getManifest() throws IOException
{
InputStream inputFile = this.getClass().getClassLoader().getResourceAsStream("META-INF/MANIFEST.MF");
Manifest manifestObj = new Manifest(inputFile);
return manifestObj;
}
}
AppService.java
#Service
public class AppService
{
#Autowired
#Qualifier("manifest")
private Manifest manifest;
#PostConstruct
public String init()
{
Attributes mainAttributes = manifest.getMainAttributes();
String buildNum = mainAttributes.getValue("Build-Number");
String customPropInfo= mainAttributes.getValue("customPropInfo");
String systemPrp1= buildNum + "_" + "SomeBusinessInfoLogic1";
String systemPrp2= customPropInfo+ "_" + "SomeBusinessInfoLogic2";
//Some Business Logic with these attributes systemPrp, systemPrp2
logger.info("System Props are updated");
}
}
I'm getting null for both buildNum and customPropInfo.
Note: I have tried creating the Manifest bean something like this which was created by me. As per the #M.Deinum suggestion I'm creating this new question here. I also tried the solutions here which didn't work for me.
#M.Deinum suggested to make use of Spring Boot's Actuator Info endpoint. But this endpoint is useful when we want to access the info outside of the application but my requirement is different as I need the data that is available in MANIFEST.MF file to perform some business operations within the application.
I get the following error when I tried this solution "/META-INF/MANIFEST.MF".
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'manifest' defined in class path resource [com/abc/AppConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [java.util.jar.Manifest]: Factory method 'getManifest' threw exception; nested exception is java.lang.NullPointerException: Cannot invoke "java.io.InputStream.read(byte[], int, int)" because "this.in" is null
Can someone please help me to read information from META/MANIFEST.MF of the Spring Boot MVC Web Application?.
UPDATE1: I get the following MainAttributes when I try to print MainAttributes. But the problem is when I try to deploy the war into external tomcat.
System.out.println("Manifest MainAttributes = " +manifestObj.getMainAttributes().keySet());
Output:
Manifest MainAttributes = [Manifest-Version, Implementation-Title, Automatic-Module-Name, Implementation-Version, Built-By, Spring-Boot-Jar-Type, Build-Jdk-Spec]
UPDATE2:
I have updated to AppService.java to print the info available in autowired Manifest object. Something like below:
#Configuration
public class AppConfig
{
#Bean("manifest")
public java.util.jar.Manifest getManifest() throws IOException
{
InputStream inputFile = new ClassPathResource("/META-INF/MANIFEST.MF").getInputStream();
Manifest manifestObj = new Manifest(inputFile);
System.out.println("Manifest Manifest-Version = " +manifestObj.getMainAttributes().getValue("Manifest-Version"));
System.out.println("Manifest KeySet = " +manifestObj.getMainAttributes().keySet());
return manifestObj;
}
}
#Service
public class AppService
{
#Autowired
#Qualifier("manifest")
private Manifest manifest;
#PostConstruct
public String init()
{
Attributes mainAttributes = manifest.getMainAttributes();
mainAttributes.forEach((k,v) -> {
System.out.println("AppService.init(): Key = "+k+", Value = "+v);
});
String buildNum = mainAttributes.getValue("Build-Number");
String customPropInfo= mainAttributes.getValue("customPropInfo");
String systemPrp1= buildNum + "_" + "SomeBusinessInfoLogic1";
String systemPrp2= customPropInfo+ "_" + "SomeBusinessInfoLogic2";
//Some Business Logic with these attributes systemPrp, systemPrp2
logger.info("System Props are updated");
}
}
I see the following output on the console:
AppService.init(): Key = Implementation-Title, Value = Apache Tomcat Bootstrap
AppService.init(): Key = Implementation-Version, Value = 9.0.12
AppService.init(): Key = Specification-Vendor, Value = Apache Software Foundation
AppService.init(): Key = Specification-Title, Value = Apache Tomcat Bootstrap
AppService.init(): Key = Class-Path, Value = commons-daemon.jar
AppService.init(): Key = Manifest-Version, Value = 1.0
AppService.init(): Key = Main-Class, Value = org.apache.catalina.startup.Bootstrap
AppService.init(): Key = Implementation-Vendor, Value = Apache Software Foundation
AppService.init(): Key = Ant-Version, Value = Apache Ant 1.9.9
AppService.init(): Key = X-Compile-Target-JDK, Value = 1.8
AppService.init(): Key = X-Compile-Source-JDK, Value = 1.8
AppService.init(): Key = Created-By, Value = some xyz
AppService.init(): Key = Specification-Version, Value = 9.0
So just by the above output, I think MANIFEST.MF is not application specific but is from commons-daemon.jar.
OK - the problem isn't that you "can't read data from META/MANIFEST.MF in Spring Boot MVC Web Application". Rather, the problem is that your code happens to be reading the WRONG MANIFEST.MF from some other, random .jar in the classpath.
One solution might be to use JarClassLoader.
Another solution, as M. Deinum suggested, might be to store the properties you wish to retrieve in application.properties (or some other "global" properties file) instead of MANIFEST.MF.
ALSO:
I assume you're probably using an IDE to develop your app (Eclipse, Netbeans, etc). If you haven't already, I would STRONGLY encourage you to familiarize yourself with your IDE's debugger: the ability to set breakpoints, display variables, single-step through method calls, etc.

FileWritingMessageHandler - adding timestamp suffix to file

I have an issue on adding timestamp suffixes to files using spring integration.
Here is my FileWritingMessageHandler bean :
public FileWritingMessageHandler getFileWritingMessageHandler(String directory) {
FileWritingMessageHandler handler = new FileWritingMessageHandler(new File(directory));
handler.setFileExistsMode(FileExistsMode.REPLACE);
handler.setExpectReply(false);
handler.setDeleteSourceFiles(true);
return handler;
}
I tried with handler.setTemporaryFileSuffix(getCurrentTimeStamp()); but it does nothing
I tried also with a DefaultFileNameGenerator :
DefaultFileNameGenerator suffixFileNameGenerator = new DefaultFileNameGenerator();
suffixFileNameGenerator.setHeaderName("id");
suffixFileNameGenerator.setExpression("payload.name + '"+ getCurrentTimeStamp()+"'");
handler.setFileNameGenerator(suffixFileNameGenerator);
A timestamp is added but it's the same for all files. They are processed at different times so I would like to append that time to the file name.
How can I achieve that ?
Thanks in advance for your help
You are getting the time once and adding it as a literal to the expression.
You need to get the timestamp at runtime instead of bean initialization time; use the T operator to invoke a static method:
suffixFileNameGenerator.setExpression("payload.name + T(System).currentTimeMillis()");

How does config file in lightbend/config works?

I'm having trouble with the substitution using lightbend config library .
I have an application.conf file with this content:
property.a = "propA"
list =
[
{
nameProp=one,
propToReplace = ${property.a}
},
{
nameProp=two,
propToReplace = ${property.a}
}
]
some.env {
property.a = "propEnvironment"
}
At some point in the code, I'm loading the property file using Configuration.load().
My goal is to subtitute the propToReplace with the value of property.a inside some.env, but after I run it I gets replace for the value outside (property.a = "propA").
Does anybody have an idea how to solve this?
Thanks in advance
You can substitute it by using environment variables, like running your program with:
-Dproperty.a=mySubstituteValue

Get token string from tokenID using Stanford Parser in GATE

I am trying to use some Java RHS to get the string value of dependent tokens using Stanford dependency parser in GATE, and add them as features of a new annotation.
I am having problems targeting just the 'dependencies' feature of the token, and getting the string value from the tokenID.
Using below specifying only 'depdencies' also throws a java null pointer error:
for(Annotation lookupAnn : tokens.inDocumentOrder())
{
FeatureMap lookupFeatures = lookupAnn.getFeatures();
token = lookupFeatures.get("dependencies").toString();
}
I can use below to get all the features of a token,
gate.Utils.inDocumentOrder
but it returns all features, including the dependent tokenID's; i.e:
dependencies = [nsubj(8390), dobj(8394)]
I would like to get just the dependent token's string value from these tokenID's.
Is there any way to access dependent token string value and add them as a feature to the annotation?
Many thanks for your help
Here is a working JAPE example. It only printns to the GATE's message window (std out), It doesn't create any new annotations with features you asked for. Please finish it yourself...
Stanford_CoreNLP plugin has to be loaded in GATE to make this JAPE file loadable. Otherwise you will get class not found exception for DependencyRelation class.
Imports: {
import gate.stanford.DependencyRelation;
}
Phase: GetTokenDepsPhase
Input: Token
Options: control = all
Rule: GetTokenDepsRule
(
{Token}
): token
-->
:token {
//note that tokenAnnots contains only a single annotation so the loop could be avoided...
for (Annotation token : tokenAnnots) {
Object deps = token.getFeatures().get("dependencies");
//sometimes the dependencies feature is missing - skip it
if (deps == null) continue;
//token.getFeatures().get("string") could be used instead of gate.Utils.stringFor(doc,token)...
System.out.println("Dependencies for token " + gate.Utils.stringFor(doc, token));
//the dependencies feature has to be typed to List<DependencyRelation>
List<DependencyRelation> typedDeps = (List<DependencyRelation>) deps;
for (DependencyRelation r : typedDeps) {
//use DependencyRelation.getTargetId() to get the id of the target token
//use inputAS.get(id) to get the annotation for its id
Annotation targetToken = inputAS.get(r.getTargetId());
//use DependencyRelation.getType() to get the dependency type
System.out.println(" " +r.getType()+ ": " +gate.Utils.stringFor(doc, targetToken));
}
}
}

How to get name correctly in Oracle's diagnosability in JDBC?

I'm following Oracle's sample code in "Diagnosability in JDBC" at : https://docs.oracle.com/cd/B28359_01/java.111/b31224/diagnose.htm
My code looks like this :
ClassLoader l = oracle.jdbc.OracleDriver.class.getClassLoader();
String loader = l.getClass().getName() + "#" + l.hashCode();
System.out.println("loader = "+loader);
javax.management.ObjectName name=new javax.management.ObjectName("com.oracle.jdbc:type=diagnosability,name="+loader);
javax.management.MBeanServer mbs=java.lang.management.ManagementFactory.getPlatformMBeanServer(); // get the MBean server
System.out.println("LoggingEnabled = "+mbs.getAttribute(name,"LoggingEnabled")); DB_Logger.java:33 // find out if logging is enabled or not
mbs.setAttribute(name,new javax.management.Attribute("LoggingEnabled",true)); // enable logging
mbs.setAttribute(name,new javax.management.Attribute("LoggingEnabled",false)); // disable logging
The out put looks like this :
loader = org.apache.catalina.loader.WebappClassLoader#929887595
The error message looks like this :
javax.management.InstanceNotFoundException: com.oracle.jdbc:type=diagnosability,name=org.apache.catalina.loader.WebappClassLoader#929887595
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getMBean(DefaultMBeanServerInterceptor.java:1095)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getAttribute(DefaultMBeanServerInterceptor.java:643)
at com.sun.jmx.mbeanserver.JmxMBeanServer.getAttribute(JmxMBeanServer.java:678)
at com.mes.tools.DB_Logger.(DB_Logger.java:33)
The output line is causing the error, so how can I get the name correctly ?
Try this, instead:
ClassLoader l = oracle.jdbc.OracleDriver.getClassLoader();
String loader = l.getName() + "#" + l.hashCode();
Oracle updated their sample code in 12c. See also: https://docs.oracle.com/database/121/JJDBC/diagnose.htm#JJDBC28887

Categories

Resources