log4j2 logfile location, one for local Eclipse Dev one during deploy - eclipse

I'm using log4j2 and have a rolling file configured in log4j2.xml as
<RollingFile name="a2.log" append="true"
fileName="C:/Dev/error_log/local_error_log_app_name.log"
filePattern="C:/Dev/error_log/local_error_log_app_name_-%d{MM-dd-yyyy}-%i.txt.gz">
This is good for local Eclipse Development but when I deploy to a JBOSS server I'd like the path and filename to be appropriate for that file system, without having to remember to edit the log4j2.xml file before deploying.
fileName="/www/logs/error_log/error_log_app_name.log"
I've seen the following posts
How to give dynamic file name in the appender in log4j.xml
Log4J2 - assigning file appender filename at runtime
and tried
fileName="$${sys:logFilename}" and fileName="${sys:logFilename}" but all that did was put a file ${sys in the Jboss bin folder `jboss-as-7.1.1.Final\bin'

Have you tried declaring a property in your config file?
The log4j2 docs have an example here:
http://logging.apache.org/log4j/2.x/manual/configuration.html#PropertySubstitution
If this does not work, please raise a ticket in the log4j2 issue tracker:
https://issues.apache.org/jira/browse/LOG4J2

When declaring a property in log4j2.xml, use double dollar signs $$
<Properties>
<Property name="filenameVariable">$${sys:errorLogFileName}</Property>
<Property name="filePatternVariable">$${sys:errorLogFilePattern}</Property>
</Properties>
and reference using single dollar sign $
<RollingFile name="a2.log" append="true"
fileName="${filename}"
filePattern="${filePattern}">
However it is not necessary to use a property. Just reference the system property directly, again with just single dollar sign
<RollingFile name="a2.log" append="true"
fileName="${sys:errorLogFileName}"
filePattern="${sys:errorLogFilePattern}">
And to the answer to my actual issue how to dynamically specify log file based on whether I am running locally in Eclipse or deployed to our server, I'm using
#Singleton
#Startup
public class StartupBean {
#PostConstruct
private void startup() {
if (File("C:/").exists()) {
System.setProperty("errorLogFileName", "C:/path/to/error_log.txt");
System.setProperty("errorLogFilePattern", "C:/path/to/error_log-%d{MM-dd-yyyy}-%i.txt.gz");
} else {
System.setProperty("errorLogFileName", "/unix/path/to/error_log.txt");
System.setProperty("errorLogFilePattern", "/unix/path/to/error_log-%d{MM-dd-yyyy}-%i.txt.gz");
}
}
}
Important! Without a system property set System.setProperty("whatever") the lookup in your log4j2.xml will fail and instead log4j will write to a file named as the first part of your lookup before the semicolon i.e. ${sys

Related

(Keycloak) Freemarker Template system properties and environment variables

We wanted to work on the Templates and tried to get the system properties that we set earlier in the standalone.xml file like this.
</extensions>
<system-properties>
<property name="testProp" value="TestVal"/>
</system-properties>
In the Docs of Keycloak its described like the following.
${some.system.property} - for system properties
${env.ENV_VAR} - for environment variables.
But nothing worked for us. We always get the following error Message “An internal server error has occurred”.
What is the right way to get the system properties and the environment variables in the Freemarker Template?
Keycloak Theme Property Documentation
is missing how to add them in the template.
It is however just a bit lower in the same document
So in theme.properties could be
customPropInThemeProperties=${env.SOME_OTHER_RESOURCE_URL}
Then uses in .ftl as
${properties.customPropInThemeProperties}
In order to use system properties in the freemarker template of keycloak, do the following configuration.
Declare your system properties in the standalone.xml
<system-properties>
<property name="UATLogin" value="http://localhost:9090" />
</system-properties>
Add variable inside theme.properties to access the system property.
UATURL=${UATLogin}
As an example, I have done the testing with register.ftl
<span>${kcSanitize(msg("backToLogin"))?no_esc}</span>

Set system properties in standalone-full.xml in wildfly 8.2

I have added system-properties tag in standalone-full.xml, but its not working in standalone mode. However, if I add the same tag in domain.xml it's working for domain mode.
<?xml version='1.0' encoding='UTF-8'?>
<server xmlns="urn:jboss:domain:2.2">
<extensions>
....
</extensions>
<system-properties>
<property name="java.util.Arrays.useLegacyMergeSort" value="true"/>
</system-properties>
</server>
According to this article on jBoss General configuration concepts
System property values can be set in a number of places in domain.xml, host.xml and standalone.xml.
Then what about standalone-full.xml?
I don't want to set it through command line and not even in java code.
In standalone it's probably too late to set it in the configuration files. You'll need to add it to the standalone.conf or standalone.conf.bat in the JAVA_OPTS environment variable. A global property like that needs to be set before anything else attempts to use java.util.Arrays.
If you have started the Wildfly server with standalone-full.xml instead of standalone.xml(the default) than this should be reflected in the start of the server:
standalone.sh -b <hostIP> -c standalone-full.xml -Dorg...
Then this will have effect on first start.
If you change something in this config file, you will need to reload Wildfly(configuration) from jboss cli:
[standalone#localhost:9990 /] :reload
For Wildfly 10 it's working nontheless. I was able to read the property for an instance started with the standalone-full.xml containing some properties.
The manual must be outdated then I guess? Because even Wildfly itself inserts a new property in the standalone-full.xml when using the Wildfly admin webinterface: http://localhost:9990 > Configuration > System Properties (Wildfly will add the property of course to the xml config which was used to start the instance). That's enough proof for me.

Error in BindJndiForEJBNonMessageBinding using ibm-ejb-jar-bnd.xml

Deploying an application in WAS 8 gives me an error:
Cannot find a match for supplied option: "[ejb.jar, ejbName, ejb.jar,META-INF/ibm-ejb-jar-bnd.xml, ejb/ejbName]" for task "BindJndiForEJBNonMessageBinding"
my entry in ibm-ejb-jar-bnd.xml
<session name="ejbName">
<interface class="com.manager.EJBNameManager" binding-name="ejb/ejbName"/></session>
my entry in deploy.jacl
[-BindJndiForEJBNonMessageBinding ejb.jar ejbName ejb.jar,META-INF/ibm-ejb-jar-bnd.xml ejb/ejbName]
my ejb.jar structure has META-INF/ibm-ejb-jar-bnd.xml also.
Was my entry in ibm-ejb-jar-bnd.xml correct? Please enlighten me on this one. Thanks.
Instead of providing the path to your ejb jar bindings (ejb.jar,META-INF/ibm-ejb-jar-bnd.xml), you should be providing the path to your ejb deployment descriptor (e.g. ejb.jar,META-INF/ejb-jar.xml).
In addition, you shouldn't even need the ejb bindings file, because you are creating the binding using JACL. The ibm-ejb-jar-bnd.xml file will automatically be created for you as a result of your deployment.
(Also, as a side note, WAS deprecated its use of JACL in WAS 7, so you should consider using jython for your wsadmin scripts instead.)

Correct way to make datasources/resources a deploy-time setting

I have a web-app that requires two settings:
A JDBC datasource
A string token
I desperately want to be able to deploy one .war to various different containers (jetty,tomcat,gf3 minimum) and configure these settings at application level within the container.
My code does this:
InitialContext ctx = new InitialContext();
Context envCtx = (javax.naming.Context) ctx.lookup("java:comp/env");
token = (String)envCtx.lookup("token");
ds = (DataSource)envCtx.lookup("jdbc/datasource")
Let's assume I've used the glassfish management interface to create two jdbc resources: jdbc/test-datasource and jdbc/live-datasource which connect to different copies of the same schema, on different servers, different credentials etc. Say I want to deploy this to glassfish with and point it at the test datasource, I might have this in my sun-web.xml:
...
<resource-ref>
<res-ref-name>jdbc/datasource</res-ref-name>
<jndi-name>jdbc/test-datasource</jndi-name>
</resource-ref>
...
but
sun-web.xml goes inside my war, right?
surely there must be a way to do this through the management interface
Am I even trying to do the right thing? Do other containers make this any easier? I'd be particularly interested in how jetty 7 handles this since I use it for development.
EDIT Tomcat has a reasonable way to do this:
Create $TOMCAT_HOME/conf/Catalina/localhost/webapp.xml with:
<?xml version="1.0" encoding="UTF-8"?>
<Context antiResourceLocking="false" privileged="true">
<!-- String resource -->
<Environment name="token" value="value of token" type="java.lang.String" override="false" />
<!-- Linking to a global resource -->
<ResourceLink name="jdbc/datasource1" global="jdbc/test" type="javax.sql.DataSource" />
<!-- Derby -->
<Resource name="jdbc/datasource2"
type="javax.sql.DataSource"
auth="Container"
driverClassName="org.apache.derby.jdbc.EmbeddedDataSource"
url="jdbc:derby:test;create=true"
/>
<!-- H2 -->
<Resource name="jdbc/datasource3"
type="javax.sql.DataSource"
auth="Container"
driverClassName="org.h2.jdbcx.JdbcDataSource"
url="jdbc:h2:~/test"
username="sa"
password=""
/>
</Context>
Note that override="false" means the opposite. It means that this setting can't be overriden by web.xml.
I like this approach because the file is part of the container configuration not the war, but it's not part of the global configuration; it's webapp specific.
I guess I expect a bit more from glassfish since it is supposed to have a full web admin interface, but I would be happy enough with something equivalent to the above.
For GF v3, you may want to try leveraging the --deploymentplan option of the deploy subcommand of asadmin. It is discussed on the man page for the deploy subcommand.
We had just this issue when migrating from Tomcat to Glassfish 3. Here is what works for us.
In the Glassfish admin console, configure datasources (JDBC connection pools and resources) for DEV/TEST/PROD/etc.
Record your deployment time parameters (in our case database connect info) in properties file. For example:
# Database connection properties
dev=jdbc/dbdev
test=jdbc/dbtest
prod=jdbc/dbprod
Each web app can load the same database properties file.
Lookup the JDBC resource as follows.
import java.sql.Connection;
import javax.sql.DataSource;
import java.sql.SQLException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
/**
* #param resourceName the resource name of the connection pool (eg jdbc/dbdev)
* #return Connection a pooled connection from the data source
* associated with resourceName
* #throws NamingException will be thrown if resource name is not found
*/
public Connection getDatabaseConnection(String resourceName)
throws NamingException, SQLException {
Context initContext = new InitialContext();
DataSource pooledDataSource = (DataSource) initContext.lookup(resourceName);
return pooledDataSource.getConnection();
}
Note that this is not the usual two step process involving a look up using the naming context "java:comp/env." I have no idea if this works in application containers other than GF3, but in GF3 there is no need to add resource descriptors to web.xml when using the above approach.
I'm not sure to really understand the question/problem.
As an Application Component Provider, you declare the resource(s) required by your application in a standard way (container agnostic) in the web.xml.
At deployment time, the Application Deployer and Administrator is supposed to follow the instructions provided by the Application Component Provider to resolve external dependencies (amongst other things) for example by creating a datasource at the application server level and mapping its real JNDI name to the resource name used by the application through the use of an application server specific deployment descriptor (e.g. the sun-web.xml for GlassFish). Obviously, this is a container specific step and thus not covered by the Java EE specification.
Now, if you want to change the database an application is using, you'll have to either:
change the mapping in the application server deployment descriptor - or -
modify the configuration of the existing datasource to make it points on another database.
Having an admin interface doesn't really change anything. If I missed something, don't hesitate to let me know. And just in case, maybe have a look at this previous answer.

Is it possible to use jboss-log4j.xml located outside from JBOSS_HOME?

Is it possible to configure JBoss 5.x to use jboss-log4j.xml located outside from JBOSS_HOME?
If yes - what should be changed?
The conf/jboss-service.xml file contains the reference to jboss-log4j.xml:
<mbean code="org.jboss.logging.Log4jService"
name="jboss.system:type=Log4jService,service=Logging"
xmbean-dd="resource:xmdesc/Log4jService-xmbean.xml">
<attribute name="ConfigurationURL">resource:jboss-log4j.xml</attribute>
I'm not sure what resource:jboss-log4j.xml means, exactly, but ConfigurationURL sounds like something you could pass in a file://-style URL to, specifying an external log4j file.