Parameter substitution in log4j2 - jndi

I need to allow deployers to specify the path for our Tomcat webapp log4j2 RollingFileLogger. I'd like to use JNDI but can use a plain -D param if I had to. This apache page seems to explain things pretty well.
Only problem is it doesn't work. I will admit to not being particularly experienced in JNDI, but I can't even get a simple JVM param to work. Reading about Property Substitution I got the impression I cannot just put the $${jndi:xxxx} in the filename attribute and that I should use a ${xxx} Property substitution instead. Unfortunately while that property substituion works fine no lookup jndi or env ever resolves.
log4j2.xml:
<Properties>
<Property name="filename">$${jndi:logPath/directory}/ief.log</Property>
</Properties>
....
<RollingFile name="RollingFileLogger" fileName="${filename}" immediateFlush="false" append="true"
Result:
2014-09-16 14:44:46,284 ERROR Unable to create file ${jndi:logPath/directory}/ief.log java.io.IOException: The filename, directory name, or volume label syntax is incorrect
As you can see the property is substituted but the lookup is not done. I am unsure what the context.xml entry should look like. But my best guess is:
<Resource name="logPath"
auth="Container"
directory="/tmp" />
I am using log4j version 2.0 but am fairly certain this is my misunderstanding not a bug. Any help clearing up what I'm doing wrong would be greatly appreciated.

I never found a JNDI browser that would work in Tomcat 7. But it did turn out to be a stupid problem. I defined this as a RESOURCE instead of an ENVIRONMENT. Just for the record the context.xml should look like:
<Environment name="logPath"
auth="Container"
type="java.lang.String"
value="/tmp" />
And log4j2 lookup is then:
<Property name="logName">$${jndi:logPath}/iefrest.log</Property>
<Property name="patternName">$${jndi:logPath}/iefrest</Property>
...
<RollingFile name="RollingFileLogger" fileName="${logName}" immediateFlush="false" append="true"
filePattern="${patternName}-%d{yyyyMMdd-HH}.log.gz">
It is worth noting that the "java:comp/env" (which is clearly documented but misleading to people that don't have a deep knowledge of JNDI - like me) actually maps to the Environment XML element and does not imply a prefix to the name attribute.
From a Log4J2 prespective it is also interesting that the filename attribute is taken EXACTLY as provided. Specifically you cannot say filename="${logName}.log". This will not parse into the desired results. However expected concatenation DOES take place on the filepattern attribute. Inconsistent but not unmanageable.

If you specify $${jndi:logPath/directory}, the lookup will add the prefix java:comp/env/, so the full value that it will look up is java:comp/env/logPath/directory. (This prefix is not added if your jndi lookup key already contains a ':' character.) Perhaps you can use a JNDI browser to see if this gives you the expected value.
Any errors that occur during this lookup will be logged to the status logger at WARN level. Status logs appear in the console. You can enable status logs by specifying <Configuration status="trace" ... in your log4j2.xml configuration file.

Related

Jmeter 3.0 can't generate the ANT HTML report

I am on the verge of pulling all my hair out, someone please help me..
I am using JMeter 3.0 and am trying to generate the dashboard report from my jtl files, but I get the error -
result.jtl' does not contain the field names header, ensure the jmeter.save.saveservice.* properties are the same as when the CSV file was created or the file may be read incorrectly
my user.properites file contains -
jmeter.save.saveservice.output_format=csv
jmeter.save.saveservice.bytes=true
jmeter.save.saveservice.label=true
jmeter.save.saveservice.latency=true
jmeter.save.saveservice.response_code=true
jmeter.save.saveservice.response_message=true
jmeter.save.saveservice.successful=true
jmeter.save.saveservice.thread_counts=true
jmeter.save.saveservice.thread_name=true
jmeter.save.saveservice.time=true
jmeter.save.saveservice.timestamp_format=ms
jmeter.save.saveservice.timestamp_format=yyyy-MM-dd HH:mm:ss
jmeter.save.saveservice.print_field_names=true
these values are the same in the jmeter.properties file as well, just to ensure I haven't lost anything...
I really can't work out why I can't get the jtl to include the headers, I have followed every guide I can find, and I seem to be doing it right..
Can someone point to me what I am missing, or include a zipped version of their jmeter with it all working that I can try and point my ant project to?
Hope someone can help.
Double check <jmeter> section of your build.xml file. Default JMeter Ant Task assumes XML out put format for .jtl result files so if you have the following line:
<property name="jmeter.save.saveservice.output_format" value="xml"/>
just comment it out or delete it and your issue should be resolved.
I don't think JMeter Ant Task respects overrides via user.properties file, it is better to use jmeterproperties attribute or explicitly specify the relevant configuration in the Ant build file like:
<target name="test">
<jmeter
jmeterhome="${jmeter.home}"
testplan ="${testpath}/${test}.jmx"
resultlog="${testpath}/${test}.jtl">
<property name="jmeter.save.saveservice.output_format" value="csv"/>
<property name="jmeter.save.saveservice.print_field_names" value="true"/>
<property name="jmeter.save.saveservice.timestamp_format" value="ms"/>
<!--etc.-->
</jmeter>
</target>
I would also recommend choosing one of jmeter.save.saveservice.timestamp_format properties (either ms or yyyy-MM-dd HH:mm:ss as it might cause problems with the dashboard generation), having duplicate property names with different values is not a very good practice.
See Five Ways To Launch a JMeter Test without Using the JMeter GUI article for more information on running JMeter tests via Ant task and other ways of kicking off a JMeter test
I had noticed before you posted, but it is correct, the XML type was hardcoded in the build.xml, now I have changed that, all is working :)

Configure spring security ldap-server attribute to use different url based on deployed environment

We are using spring security and have it working well. I am trying to figure out one thing that has not being obvious - how do I configure ldap-server attribute to use different url based on deployed environment?
This is what I have that is working:
<ldap-server url="ldap://testserver:port/o=blah" manager-dn="cn=bind,ou=Users,o=blah" manager-password="password"/>
<authentication-manager id="authenticationManager" alias="authenticationManager">
<ldap-authentication-provider
user-search-filter="(cn={0})"
user-search-base="ou=Users"
group-search-filter="(uniqueMember={0})"
group-search-base="ou=groups"
group-role-attribute="cn"
role-prefix="none">
</ldap-authentication-provider>
Now, how do I configure it to use a different url based on deployed environment?
thanks in advance,
Sharath
I've done that with Spring profiles:
In your spring.*.xml config file use this at the end of your file:
<beans profile="production">
...
</beans>
<beans profile="local">
...
</beans>
As VM Arguments the used profile must be provided:
-Dspring.profiles.active=production
Regards
You can use the url as variables and set them in a properties file.
To change the properties file should be easier. I know you can do that with Maven - with jar or war plugin depending on packaging, including generating two (or more) packages with one execution - but I suppose you can with Ant or other managers too.
Of course, you could use that solution to change the whole xml, but it's easier to do that with a properties file because that way, when changing the configuration, the markup will not be in the way, only variables and values.

remove application name from URL

my site uses JSF and the url appears to be, http://mysitename.com/wompower6/faces/home.xhtml
I am using prettyfaces, so if I use the following in pretty-config.xml, i can change the name to http://mysitename.com/wompower6/home
<url-mapping id="home">
<pattern value="/home" />
<view-id value="/faces/home.xhtml" />
</url-mapping>
my questions are
how can i remove the application
name wompower6 , so that the url
becomes mysitename.com/home ?
in my web.xml, i have
<welcome-file>home.xhtml</welcome-file>,
but this does not seem to work. When
i type, mysitename.com, it does not
get mapped to home.xhtml. any clue
here?
how can i remove the application name wompower6 , so that the url becomes mysitename.com/home?
This is a webapp <Context> setting and configuration is dependent on the servletcontainer used. If you're for example using Tomcat, then there are basically 2 options to make your webapp the root webapp.
Rename the WAR file to ROOT.war and Tomcat will by default deploy it on context root.
Set path attribute of <Context> element in Webapp/META-INF/context.xml (or Tomcat/conf/server.xml, depending where you'd like to define it) to an empty String. E.g.
<Context path="" ...>
Other containers support similar constructs. Consult their documentation for detail. If you're using an IDE like Eclipse, then you can also set it in the Web Project Settings property of the project properties (rightclick project and choose Properties). Set the Context root value to just /.
in my web.xml, i have home.xhtml, but this does not seem to work. When i type, mysitename.com, it does not get mapped to home.xhtml. any clue here?
I assume that you're talking about the <welcome-file> setting. This has to point to a physically existing file, not to a virtual URL, such as /faces/*. There are basically two ways to overcome this:
Provide a physically existing /faces/home.xhtml file (it can even be left empty).
Replace the ugly /faces/* URL pattern of the FacesServlet mapping in web.xml by *.xhtml so that it will just kick in on every request for a XHTML file.
<url-pattern>*.xhtml</url-pattern>
This way you don't need to fiddle with /faces/* URL patterns.

Valid <property> names in Ant

I'd like to set some properties in my ant build file, the names of which, are based on ant's build in properties. In particular, I'd like to set a property like:
<property name="${ant.project.name}.compiled" value="true" />
However, when I tried this the ${ant.project.home} portion was not expanded.
Is it possible to use the value of properties as the names of other properties, and if so, how?
<property name="name.holder" value="iamholder" />
<property name="${name.holder}.flag" value="true" />
<echoproperties></echoproperties>
result:
[echoproperties] iamholder.flag=true
this is definitely valid ant code and the property iamholder.flag gets the value of true.
If ${name.holder} does not get expanded, it means it has not been set yet (like if the first line in my sample was missing).
Anyways, this still does not quite solve your problem, as you have pretty much no means of getting the value of this property as you don't know it's name and you can't do a nested resolve in pure ant. Depending on what you are trying to do it could still be useful to you though. This one would work (keep in mind, that until 1.8 the value is irrelevant as long as the property is set):
<target name="compile_stuff" unless="${name.holder}.flag">
<echo>compiling...</echo>
</target>
To really get the value of such a property you have to use ant-contrib's propertycopy as suggested in one of the answers. That way you can get the value in a property whose name you know. Just make sure to do the trick just before use and set the override parameter to true (your post implies that you would be setting more properties like these, but without override your final property could not be changed). Another option for working with such properties is to use ant macros.
I think the only way is to echo your values to a .properties file and then load them back.
However, you should ask yourself if you really need it; when I last used ant I tried to do the same thing but concluded I didn't really need to.
Is
$ant.project.home.compiled
not just as useful?
It can be done, a bit ugly, though. You need the < propertycopy > task from ant-contrib for this. The following shows an example
<property name="projectNameCompiled" value="${ant.project.name}.compiled" />
<property name="${projectNameCompiled}" value="true" />
<propertycopy property="final" from="${ant.project.name}.compiled" />
The property final contains the value true.
There are several ways to achieve that, see Ant FAQ
One possible solution via macrodef simulates the antcontrib / propertycopy task but doesn't need any external library.

xmltask confused about dtd

I'm trying to use xmltask for ant to modify a file in a subdirectory:
project/path/to/file.xml
The file refers to a DTD like this:
<!DOCTYPE data SYSTEM "mydtd.dtd">
I don't have the flexibility to change these documents.
This DTD is stored in the same subdirectory, which has always worked fine:
project/path/to/mydtd.dtd
Unfortunately, xmltask is trying to locate the dtd in my project's top-level directory, which is where my build file is located, and where I run from:
[xmltask] java.io.FileNotFoundException: /home/me/project/mydtd.dtd (The system cannot find the file specified)
I see in the xmltask documentation that I can correct this with an xmlcatalog element to tell it where to look up the file. But I need to use a dtd element, and I can only find examples for this element, not documentation; the examples show only a publicId, and if I understand XML correctly this document does not have one. I shouldn't need to specify this, anyway, right, since my document already says my DTD is stored locally and shows right where it is?
Why isn't xmltask finding the DTD correctly? What's the best way to correct or work around this situation?
An XML Catalog is the way to go here, it just needs a bit more perseverance.
As you correctly pointed out, the standard Ant <XmlCatalog> type only allows you to specify public DTD references when using the inline syntax, which is of no use to you. However, <XmlCatalog> also lets you specify a standard OASIS-syntax catalog, which is far richer, including resolving SYSTEM DTD references.
An OASIS catalog (full spec here) looks like this:
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<system systemId="mydtd.dtd" uri="project/path/to/mydtd.dtd"/>
</catalog>
You can then reference this catalog from the <XmlCatalog>:
<xmlcatalog refid="commonDTDs"/>
<catalogpath>
<pathelement location="path/to/oasis.catalog"/>
</catalogpath>
</xmlcatalog>
And that's that. It's a good idea to build up a reusable OASIS catalog file, and refer to it from various XML-related Ant tasks, all of which can use <XmlCatalog>.
As an alternative, it looks like I can skip the whole validation by creating a blank file with the same name as the DVD file, and then deleting the file when I am done. Odds are I am going to go that route instead of using the catalog.
xmltask isn't finding it because it is looking in the current working directory. Ant allows you to specify a base directory using the basedir attribute of the <target> element. So I suggest you try this:
<target basedir="path/to" ...>
<xmltask...
</target>
It strikes me that it is not the XML/DTD that you really have the problem with, but getting xmltask to interact with the two of them as you want.
If that fails, you could use the Ant Copy task to copy the XML and DTD to the root folder before processing with xmltask, then copying back again.
Have you tried:
<!DOCTYPE data SYSTEM "./path/to/mydtd.dtd">
? Or an absolute path?
Also, you can find <dtd> description here.
I had a similar problem where an XML file had a doctype with SYSTEM reference that could not be changed.
<!DOCTYPE opencms SYSTEM "http://www.opencms.org/dtd/6.0/opencms-modules.dtd">
I first went down the road and created a catalog file with the OASIS catalog as described above, but to be able to use external catalogs I had to include the Apache Commons Resolver 1.1 (resolver.jar) in the Ant classpath (see http://ant.apache.org/manual/Types/xmlcatalog.html).
Because I had multiple machines on which this build was supposed to run this seemed overkill, especially since xmltask worked fine if I just removed the doctype definition. I wasn't allowed to remove it permanently because the doctype was needed elsewhere.
Ultimately I used this workaround: I commented out the doctype definition using Ant's replace task, ran the xmltask, and then put the doctype back into the file.
<replace file="myxmlfile.xml">
<replacetoken><!DOCTYPE opencms SYSTEM "http://www.opencms.org/dtd/6.0/opencms-modules.dtd"></replacetoken>
<replacevalue><!-- !DOCTYPE opencms SYSTEM "http://www.opencms.org/dtd/6.0/opencms-modules.dtd" --></replacevalue>
</replace>
<xmltask .../>
<replace file="${local.opencms.webapp.webinf}/config/opencms-modules.xml">
<replacetoken><!-- !DOCTYPE opencms SYSTEM "http://www.opencms.org/dtd/6.0/opencms-modules.dtd" --></replacetoken>
<replacevalue><!DOCTYPE opencms SYSTEM "http://www.opencms.org/dtd/6.0/opencms-modules.dtd"></replacevalue>
</replace>

Resources