Jetty: load a server bean from war before initialization - authentication

I have a webapp being loaded from a Jetty server.
I want to load a bean implementing a MappedLoginService inside the webapp (not from the server) before the webapp starts loading.
Is there any way?
I tried to load the bean in the webapp post-construct and in webapp application class (javax.ws.rs.Application), without success.

Put the initialization in the WEB-INF/jetty-web.xml file.
That will load it during WebApp initialization, before the Servlet layer initialization kicks off.

I follow Joakim answer creating a WEB-INF/jetty-web.xml file and it worked. I just want to extend the answer adding a sample jetty-web.xml that prints something before servlet is initiated:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure id="context" class="org.eclipse.jetty.webapp.WebAppContext">
<Get class="java.lang.System" name="out">
<Call name="println">
<Arg>Hello world!</Arg>
</Call>
</Get>
</Configure>
More information about jetty-web.xml syntax here.

Related

Custom resources equivalent to jetty JNDI resource

I have a web application which is until now deployed to a jetty server but now in order to use other JavaEE services I'm shifting to Payara (Glassfish) container. However I can't find how to provide additional JNDI resources as configuration to paraya.
Currently I have some resources like this defined in my jetty's context.xml file:
<New id="some_resource" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg>
<Ref refid='wac'/>
</Arg>
<Arg>resource/path</Arg>
<Arg>
<New class="com.example.some.Class">
<!-- constructor parameters -->
<Arg type="java.lang.String">some string</Arg>
<Arg type="java.lang.Integer">0</Arg>
</New>
</Arg>
</New>
this simply calls the custom class constructor with given parameters and puts the result into given resource/path address.
Is this possible to be done in payara micro?
It's possible to create a custom resource that is exposed via JNDI, though GlassFish/Payara support only primitive types by default. For other types you would need to add a custom factory in the server classpath.
Custom resources in Payara/GlassFish are defined in domain.xml, in element custom-resource. Best way to define a custom resource is either using Admin Console (Resources -> JNDI -> Custom resources) or asadmin command.
For a string value "some string" under a JNDI resource/path, the asadmin would look like this:
asadmin> create-custom-resource --restype java.lang.String --factoryclass org.glassfish.resources.custom.factory.PrimitivesAndStringFactory --property value="some string" "resource/path"
In Payara Micro, you can either pass domain.xml using --domainConfig argument, or you can execute the same asadmin command from within your application, using PayaraMicroRuntime.run() (documented here)

KEYCLOAK unknown authenticator error - Client Adapter installed

I am trying to setup Keycloak with Tomcat 8.
I followed the instruction carefully. I downloaded the Client Adapter for Tomcat8 and copied all the jar into $CATALINA_HOME/lib directory. I modified my web.xml login-config to use KEYCLOAK. Yet when I started Tomcat I kept getting Severe Error Unknown Authenticator??
Anywhere I googled everyone said you have to install the Client Adapter but.. in my case IT IS ALREADY THERE!!! HELP!!
I think you forgot to create a META-INF directory beside the WEB-INF and put a file named context.xml into it:
The contents of this file has to be
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Valve className="org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve"/>
</Context>
This is not needed if you deploy the war into WildFly. I had the same problem when I tried to transfer a well working webApp from WildFly to Tomcat.

Arquillian tomee remote

Using Arquillian 1.1.4.Final and Tomee 1.6.0.2
Took the tomee-plus-remote profile setup from the Tomee information about arqullian adapters and put it into the Maven pom.xml (with activeByDefault true).
Goal is to deploy a MQ JCA rar into the remote Tomee and configure a connection factory to MQ.
Set the arqullian.xml initially to:
<container qualifier="tomee" default="true">
<configuration>
<property name="httpPort">-1</property>
<property name="stopPort">-1</property>
</configuration>
</container>
Running via JUnit not sure why the webprofile is initialized and started rather than plus (when I have tomee plus specified in Maven):
Info: Succeeded in installing singleton service
jun 11, 2014 11:07:52 FM org.apache.openejb.config.ConfigurationFactory init
Info: openejb configuration file is 'C:\Users\MYG\AppData\Local\Temp\arquillian-apache-tomee\apache-tomee-webprofile-1.6.0.2\conf\tomee.xml'
Another thing is how to load a tomee.xml configuration. Thought, the "serverXml" in the arquillian.xml (set to src/test/resources/tomee.xml) would work but then everything inside that xml is not recognized as a valid rule. Can't add directives like Deployments as one does with resources. So how to configure the remote tomee from arquillian?
Yeah, tomee.xml was not really designed for arquillian.xml since all its config can be passed to properties attribute of tomee container using properties format
By adding a conf property to the arquillian.xml to for example src/test/conf where there is a tomee.xml file then it is loaded. This must be Tomee thing that I didn't know about until now.

org.apache.commons.dbcp.SQLNestedException on tomcat7

I've been fighting with my tomcat server for a while now and it still doesn't work.
I'm using tomcat7, on Debian Wheezy, with PostgreSQL v9.1.
I tried everything possible, and here is what I'm keeping on getting :
database.DataBaseException: Database error while trying to get a new connection. Error information: org.apache.commons.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'
database.Connection$.getConnection(Connection.scala:20)
database.Users$.createRegisteredUser(Users.scala:58)
controllers.page.CreateAccountController.before(CreateAccountController.scala:36)
controllers.page.AbstractPageController.processRequest(AbstractPageController.scala:52)
controllers.page.AbstractPageController.doPost(AbstractPageController.scala:79)
javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
I have access to the application pages when I'm running my application and my tomcat server, so far I configured tomcat well enough for this, but as soon as I'm having an action that involves a request to the database (creation of user, etc.), I get this error !
As for the general context of the web application, I've started helping on an already existing project, I installed tomcat7 and cloned the source on my laptop. It works well with the other people working on it - and I haven't made any change to the application code so far (the code works fine): so the error definitely comes from my tomcat configuration and not from the code.
To configure a Tomcat7 server for a web application, what we have to do to configure is creating a context.xml in the META-INF/ directory right ?
I've also added a for the data source to the WEB-INF/web.xml file but it doesn't seem to be mandatory to have a tomcat7 application data source work fine.
I've copied and past my META-INF/context.xml file to Catalina/localhost/ directory with .xml.
I've added the postgres jdbc jar to /usr/share/tomcat7/lib (I've seen a lot of forum posts talking about a conf/lib but I can't find it so I figured it's this lib)
I've read things about tweaking with the tomcat context.xml file and whatnot, but there are pros and cons, and anyway it doesn't work either for me.
Here is my context.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/dbname"
auth="Container"
type="javax.sql.DataSource"
username="user1"
password="user1"
driverClassName="org.postgresql.Driver"
url="jdbc:postgresql://localhost:5432/dbname"
maxActive="8"
maxIdle="4"/>
<Environment name="encryptionKey" type="java.lang.String" value="<the key>" override="false"/>
</Context>
What I added to the WEB-INF/web.xml:
<resource-ref>
<res-ref-name>jdbc/dbname</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
The code sample where it all starts (application written in scala) :
private val ds: DataSource = new javax.naming.InitialContext().lookup("java:comp/env/jdbc/dbname").asInstanceOf[DataSource]
private var connec: java.sql.Connection = null
def getConnection(): java.sql.Connection = {
try {
if (connec == null) {
connec = ds.getConnection() //here is raised the error
connec.setAutoCommit(false)
}
connec
} catch {
case ex: SQLException => throw new DataBaseException("Database error while trying to get a new connection. Error information: " + ex.toString())
}
}
I tried to run the application without context.xml and without the copy of if in the Catalina/localhost directory, and I get the same error. I guess the server just doesn't find my context.xml file ?
The last thing is I've compared my context.xml with some other people from the project, and they have exactly the same - and it works for them (except the db name and password that depends on what they chose)....
I also made sure the port 5432 is the right one, and it is.
Yes, it's pretty puzzly !
If you want more precision (I might be missing relevant things) don't hesitate to ask me !

NLog in WCF Service

Can I use NLog in a WCF Service? I am trying to but cannot get it to work.
First I set up a simple configuration in a Windows Forms application to check that I was setting up correctly and this wrote the log file fine (I am writing to a network location using name and not IP address).
I then did exactly the same thing in the WCF Service. It did not work.
To check permissions I then added some code to use a TextWriter.
TextWriter tw = new StreamWriter(fileName);
tw.WriteLine(DateTime.Now);
tw.Close();
This worked OK so I know I can write to the location.
Check that your NLog.config file is in the same directory as your .svc file and NOT the Bin directory.
If you've just added the config file to the WCF project, then published it you will probably find your config file has been copied to the bin directory which is why NLog can't find it. Move it to up a level then restart the website hosting the service (to make sure the change is picked up).
This had me stumped for a while this morning!
Put your NLog config in the web.config file. Like so:
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>
. . . (lots of web stuff)
<nlog>
<targets>
<target name="file" xsi:type="File" fileName="${basedir}/logs/nlog.log"/>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="file" />
</rules>
</nlog>
</configuration>
See my comment to your original question for how to turn on NLog's internal logging.
To turn on NLog's internal logging, modify the top of you NLog config to look like this:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.mono2.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogLevel="Trace"
internalLogFile="nlog_log.log"
>
The key parts are internalLogLevel and internalLogFile.
You can also set internalLogToConsole to true or false to direct the internal logging to the console.
There is another setting, throwExceptions, that tells NLog whether or not to throw exceptions. Ordinarily, this is set to false once logging is successfully configured and working. You can set it to true to help determine if your problem is due to an NLog error.
So, if you had all of those options enabled, the top of your NLog configuration might look like this:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.mono2.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogLevel="Trace"
internalLogFile="nlog_log.log"
internalLogToConsole="true"
throwExceptions="true"
>
My first guess is that NLog is not finding the config information. Are you using an external config file (NLog.config) or "inline" configuration (in your app.config or web.config)? In your project, is(are) your config file(s) marked (in Properties) as Copy Always?