spring-boot property placeholder - properties

I'm not able to figure out why I am not able to inject values into my application.properties file in spring-boot. external property into the logging.file variable. I have an application.properties file which looks like this
logging.file=${mylogfile}
server.port=${myport}
with corresponding Spring-boot Application class
#PropertySources({
#PropertySource("file:///c:/myfolder/externalprops.properties"),
})
#Configuration
#EnableAutoConfiguration
#ComponentScan
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
and external property file
mylogfile=myoutput.log
myport=8060
When I run my spring-boot 1.0.2.REL application I get the following exception every time I try to inject mylogfile into the logging.file property in application.properties
Exception in thread "main" java.lang.IllegalArgumentException: Could not resolve placeholder 'mylogfile' in string value "${mylogfile}"
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:174)
Note that I am not having any problems injecting and starting up the application if I inject the server port number on its own.
I am going around in circles on this issue and cannot figure out what I am doing wrong.

I don't think you can use #PropertySource to inject values into "application.properties" - the latter has to be parsed and ready to use before any #Configuration is read, or even known about. Your external properties could go in "${user.dir}/application.properties" and I think that would achieve what you are trying to do.

Related

Cannot create a secure XMLInputFactory when calling Apache CXF Client from Plain Java

I am trying to call a Apache CXF Service from a Plain Java code as follows
public static void main(String args[])
{
Call Apache CXF Service ....
}
I dont get any compile time error, but getting Runtime exception as follows
Exception in thread "main" java.lang.RuntimeException: Cannot create a secure XMLInputFactory
at org.apache.cxf.staxutils.StaxUtils.createXMLInputFactory(StaxUtils.java:314)
at org.apache.cxf.staxutils.StaxUtils.getXMLInputFactory(StaxUtils.java:264)
at org.apache.cxf.staxutils.StaxUtils.createXMLStreamReader(StaxUtils.java:1457)
at org.apache.cxf.staxutils.StaxUtils.read(StaxUtils.java:1110)
at org.apache.cxf.bus.extension.XmlExtensionFragmentParser.getExtensions(XmlExtensionFragmentParser.java:46)
at org.apache.cxf.bus.extension.ExtensionManagerImpl.load(ExtensionManagerImpl.java:183)
at org.apache.cxf.bus.extension.ExtensionManagerImpl.load(ExtensionManagerImpl.java:159)
at org.apache.cxf.bus.extension.ExtensionManagerImpl.load(ExtensionManagerImpl.java:108)
at org.apache.cxf.bus.extension.ExtensionManagerBus.<init>(ExtensionManagerBus.java:121)
at org.apache.cxf.bus.extension.ExtensionManagerBus.<init>(ExtensionManagerBus.java:134)
at org.apache.cxf.bus.CXFBusFactory.createBus(CXFBusFactory.java:40)
at org.apache.cxf.bus.CXFBusFactory.createBus(CXFBusFactory.java:36)
at org.apache.cxf.bus.CXFBusFactory.createBus(CXFBusFactory.java:32)
at org.apache.cxf.BusFactory.getDefaultBus(BusFactory.java:106)
at org.apache.cxf.BusFactory.createThreadBus(BusFactory.java:243)
at org.apache.cxf.BusFactory.getThreadDefaultBus(BusFactory.java:227)
at org.apache.cxf.BusFactory.getThreadDefaultBus(BusFactory.java:214)
at org.apache.cxf.jaxws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:89)
at javax.xml.ws.Service.<init>(Unknown Source)
The dependencies I have are as follows
cxf-rt-frontend-jaxws-2.7.12.jar
cxf-api-2.7.12.jar
woodstox-core-asl-4.4.0.jar
stax2-api-3.1.4.jar
xmlschema-core-2.1.0.jar
cxf-rt-core-2.7.12.jar
jaxb-impl-2.1.13.jar
cxf-rt-bindings-soap-2.7.12.jar
cxf-rt-databinding-jaxb-2.7.12.jar
cxf-rt-bindings-xml-2.7.12.jar
cxf-rt-frontend-simple-2.7.12.jar
cxf-rt-ws-addr-2.7.12.jar
cxf-rt-ws-policy-2.7.12.jar
cxf-rt-transports-http-2.7.12.jar
Please help me solve this error
Note:- I don't have pom.xml. I use traditional "lib" folder to place my dependent jars
I added these three lines and worked fine
Properties props = System.getProperties();
props.setProperty("org.apache.cxf.stax.allowInsecureParser", "1");
props.setProperty("UseSunHttpHandler", "true");

Arquillian - programmatic configuration

I am writing integration tests using Arquillian with embedded glassfish 3.1.2.2 using TestNG. I want to be able to run those tests in parallel, and for this case i need to dynamically configure glassfish ports and database name (we already have this set-up, and I want to reuse it of arquillian tests). What I am missing is a 'before container start' hook, where I could prepare the database, lookup free ports and update my glassfish configuration (domain.xml, could also be glassfish-resources.xml). Is there a 'clean' solution for this, or my usecase was not foreseen by Arquillian developers?
The hacky way I solved it currently is to override arquillian's beforeSuite method but this one gets called twice - at test startup and then in the container (therefore my pathetic static flag). Secondly, this solution would not work for JUnit based tests as there's no way to intercept arquillian's before suite:
public class FullContainerIT extends Arquillian {
private static boolean dbInitialized;
//#RunAsClient <-supported by #Test only
#Override
#BeforeSuite(groups = "arquillian", inheritGroups = true)
public void arquillianBeforeSuite() throws Exception {
if (dbInitialized == false) {
initializeDb();
dbInitialized = true;
}
super.arquillianBeforeSuite();
}
}
Some ideas I had:
+ having #BeforeSuite #RunAsClient seems to be what I need, but #RunAsClient is supported for #Test only;
+ I have seen org.jboss.arquillian.container.spi.event.container.BeforeStart event in Arquillian JavaDocs, but I have no clue how to listen to Arquillian events;
+ I have seen there is a possibility to have #Deployment creating a ShrinkWrap Descriptor, but these do not support Glassfish resources.
I found a clean solution for my problem on JBoss forum. You can register a LoadableExtension SPI and modify the arquillian config (loaded from xml). This is where I can create a database and filter glassfish-resources.xml with proper values. The setup looks like this:
package com.example.extenstion;
public class AutoDiscoverInstanceExtension
implements org.jboss.arquillian.core.spi.LoadableExtension {
#Override
public void register(ExtensionBuilder builder) {
builder.observer(LoadContainerConfiguration.class);
}
}
package com.example.extenstion;
public class LoadContainerConfiguration {
public void registerInstance(#Observes ContainerRegistry, ServiceLoader serviceLoader) {
//Do the necessary setup here
String filteredFilename = doTheFiltering();
//Get the container defined in arquillian.xml and modify it
//"default" is the container's qualifier
Container definition = registry.getContainer("default");
definition.getContainerConfiguration()
.property("resourcesXml", filteredFilename);
}
}
You also need to configure the SPI Extension by creating a file
META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
with this contents:
com.example.extenstion.AutoDiscoverInstanceExtension

Camel aws-s3 not working

I am trying to create a camel route to transfer a file from an FTP server to an AWS S3 storage.
I have written the following route
private static class MyRouteBuilder extends RouteBuilder {
#Override
public void configure() throws Exception
{
from("sftp://<<ftp_server_name>>&noop=true&include=<<file_name>>...")
.process(new Processor(){
#Override
public void process(Exchange ex)
{
System.out.println("Hello");
}
})
.to("aws-s3://my-dev-bucket ?
accessKey=ABC***********&secretKey=12abc********+**********");
}
The issue is, this gives me the following exception:
Exception in thread "main" org.apache.camel.FailedToCreateRouteException: Failed to create route route1 at: >>> To[aws-s3://my-dev-bucket?accessKey=ABC*******************&secretKey=123abc******************** <<< in route: Route(route1)[[From[sftp://<<ftp-server>>... because of Failed to resolve endpoint: aws-s3://my-dev-bucket?accessKey=ABC***************&secretKey=123abc************** due to: The request signature we calculated does not match the signature you provided. Check your key and signing method.
I then tried to do this the other way. i.e.writing a method like this:
public void boot() throws Exception {
// create a Main instance
main = new Main();
// enable hangup support so you can press ctrl + c to terminate the JVM
main.enableHangupSupport();
// bind MyBean into the registery
main.bind("foo", new MyBean());
// add routes
AWSCredentials awsCredentials = new BasicAWSCredentials("ABC*****************", "123abc*************************");
AmazonS3 client = new AmazonS3Client(awsCredentials);
//main.bind("client", client);
main.addRouteBuilder(new MyRouteBuilder());
main.run();
}
and invoking using the bound variable #client. This approach does not give any exceptions, but the file transfer does not work.
To make sure that there's nothing wrong with my approach, I tried aws-sqs instead of aws-s3 and that works fine (file succesfully transfers to the SQS queue)
Any idea why this is happening? Is there some basic issue with "aws-s3" connector for camel?
Have you tried of using RAW() function to wrap as like RAW(secretkey or accesskey).
It will help you to pass your keys as it is without encoding.
Any plus signs in you secret key need to be url encoded as %2B, in your case **********+*********** becomes **********%2B***********
When you configure Camel endpoints using URIs then the parameter values gets url encoded by default.
This can be a problem when you want to configure passwords as is.
To do that you can tell Camel to use the raw value, by enclosing the value with RAW(value). See more details at How do I configure endpoints which has an example also.
See Camel Documentation
Your url should looks like:
aws-s3:bucketName?accessKey=RAW(XXXX)&secretKey=RAW(XXXX)

An EJB is in a JAR but is not found by the WAR next to in in an EAR

I have the structure described below, but I cannot make it so MyWebService has its member myService not null. The code of MyWebService is properly executed when I call the webservice. When I look at the JBoss logs, I keep seeing that MyServiceBean has several JNDI bindings allocated to it.
So how do I bind MyServiceBean to MyWebService?
Thanks!
my-ejb.jar:
#Local
public interface MyServiceBeanLocal {
...
}
#Stateless
public class MyServiceBean implements MyServiceBeanLocal {
...
}
my-web.war:
#Webservice(...)
public class MyWebService {
#EJB
MyServiceBeanLocal myService;
...
}
my-ear.ear:
* my-ear.ear
|-* my-web.war
|-* my-ejb.jar
Have you tried using MyServiceBeanLocal as a Remote interface ? You are trying to use dependency injection from a Web module and for a Local Interface .This is not actually suggested. Anyway, At first try to make the interface #Remote . If still it doesn't work try to use`Remote Look up from the Web module for your Remote interface link
I use CXF. CXF is not an EJB container, hence the issues I got.
I had to manually bind the EJBs, using their full name.

EJB Injection failure on deploy

I've got a problem exxh EJB's.
First of all, my setup: I am using GlassFish & JEE6. I have got a REST-Service packaged as a WAR and a bean packaged as an EJB-Jar. They are not inside an EAR.
The EJB should be used from the REST-WAR via #EJB, but when I try to deploy the WAR, GlassFish shows this error:
Error occurred during deployment:
Exception while deploying the app [exx-upload-1.0] : Cannot resolve reference Local ejb-ref name=com.ex.exx.model.FileUpload/ocr,Local 3.x interface =com.ex.exx.api.IOCRService,ejb-link=null,lookup=,mappedName=,jndi-name=,refType=Session. Please see server.log for more details.
(The EJB was deployed before without any erros).
I have no clue why. Here is the EJB Code:
Interface:
#Local
public interface IOCRService {
public String performOCRonImage(BufferedImage input);
}
and Implementation:
#Stateless
#LocalBean
public class OCRScanner implements IOCRService {
private Logger logger = Logger.getLogger(this.getClass().getName());
private final static String NOT_RECOGNIZED = "Can not regocnize text";
/**
* Default constructor.
*/
public OCRScanner() {
logger.log(Level.INFO, "### OCR SCANNER BUILD" + this);
}
public String performOCRonImage(BufferedImage input) {
logger.log(Level.INFO, "### OCR SCANNER CALLED" + this);
}
...
And here is the important part in the WAR:
public class FileUpload {
private final File PROPERTIES_FILE = new File(
"fileUploadProperties.properties");
private final String PARAMETER_NAME = "file";
private final Logger logger = Logger.getLogger(this.getClass().getName());
#EJB
private IOCRService ocr;
public Response uploadFile(...) {
// do some stuff
logger.log(Level.INFO, "### EJB" + ocr.toString())
}
Anny suggestions? I can not find my failure here.
Solved this, by replaceing #Local with #Remote.
This works, however, I am not satisfied as I do not understand why.
Basically, given the specs (eg. explained in the tutorial), an application can only access other application's EJB, if they are decorated with #Remote.
Thus, you have 3 options:
decorate your EJB with #Remote (what you have done),
package both together inside an ear (as they would reside in the
same application then). But if you intent to deploy them in seperate
applications or even seperate servers, use 1.)
use CDI with #Inject, but this will still only discover the EJB if
either in the same application, or decorated as #Remote if not.
HTH,
Alex
You should not use #EJB if the target is not an EJB. I guess this is your case because you are trying to inject into a class in your WAR.
Instead use:
#Inject
private IOCRService ocr;
Basically, #Inject is better in most cases, because:
it is more typesafe,
it supports #Alternatives
it is aware of the scope of the injected object.
Another solution it's to add #Stateless(name=""), this worked form