standalone.bat
set "DBO_PATH=D:\test"
standalone.xml
<subsystem xmlns="urn:jboss:domain:naming:2.0">
<bindings>
<simple name="java:propertiesFileName" value="${DBO_PATH}/test.properties"/>
</bindings>
<remote-naming/>
</subsystem>
How to set the properties to Wildfly picks them up ??
How to use a relative path in the value standalone.xml
You are almost there. In order to achieve the goal, you need to do following:
Set environment variable like set "FOO=bar"
Then change your standalone.xml to contain reference to ${env.FOO}: <simple name="java:/Foo" value="${env.FOO}/test.properties"/>.
You can check if the solution is working by running following Java EE 6+ code
#Singleton
#Startup
public class StartupBean {
#Resource(lookup="java:/Foo")
String foo;
#PostConstruct
public void start() {
System.out.println("java:/Foo = " + foo);
}
}
Please refer to http://www.mastertheboss.com/jboss-server/jboss-configuration/how-to-use-environment-variables-in-standalone-xml-or-host-xml for another possible solution.
Related
I've added the CDI feature to the server.xml file<feature>cdi-1.2</feature>.
My maven module contains the beans.xml inside the <module_name>/src/main/resources/META-INF folder.
This is the beans.xml content:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.1" bean-discovery-mode="all">
</beans>
But when I use the #Inject annotation it doesn't work, my bean is always null.
Code:
package ch.webapp.presentation;
...
#Path("/test/")
public class MyController {
#Inject
private MyService myService;
#GET
#Path("/foo/{count}")
#OAuthSecurity(scope = "login")
#Produces("application/json")
public Response news(#PathParam("count") int count) {
return Response
.ok(myService.getBar(count))
.build();
}
}
EDIT:
That's my bean
package ch.webapp.service;
...
#RequestScoped
public class MyService {
public String getBar(int count) {
return "foo";
}
}
I initialize jax-rs by extended the MFPJAXRSApplication class
package ch.webapp;
...
public class AccountApplication extends MFPJAXRSApplication {
#Override
protected void init() throws Exception {
}
#Override
protected void destroy() throws Exception {
}
#Override
protected String getPackageToScan() {
return getClass().getPackage().getName();
}
}
Environment details:
Launching mfp (WebSphere Application Server 8.5.5.8/wlp-1.0.11.cl50820151201-1942) on Java HotSpot(TM) 64-Bit Server VM, version 1.8.0_172-b11 (en_CH)
Console Product version: 8.0.0.00-20180717-175523
What's wrong?
First it seems that websphere jax-rs implementation does not integrate jax-rs resources automatically unless you annotate them appropriately.
Put the jax-rs in a CDI managed context by annotating it appropriately
#Path("/test/")
#javax.enterprise.context.RequestScoped
public class MyController {
#Inject
private MyService myService;
#GET
#Path("/foo/{count}")
#OAuthSecurity(scope = "login")
#Produces("application/json")
public Response news(#PathParam("count") int count) {
return Response
.ok(myService.getBar(count))
.build();
}
}
Also be sure that the annotation used for your service is
#javax.enterprise.context.RequestScoped
Based on the inputs provided by you please go through the below checklist.
Your services and controllers are in the same module and its packaging type is war, So you must place your beans.xml in this path src/main/resources/WEB-INF/beans.xml. (If this is Java EE 7 application then beans.xml is optional.
In your AccountApplication class try hardcoding the package name to ch.webapp.presentation
#Override
protected String getPackageToScan() {
return "ch.webapp.presentation";
}
This is just to check Behaviour of MFPJAXRSApplication.getPackageToScan() method whether it is scanning the specified package only or its child packages too.
Except these, everything seems fine to me. If this still doesn't work add complete application startup logs so that community can find the root cause of it.
This is classical mistake. CDI works for managed beans (for instance EJB's and servlets). If you want to enable it on your JAXRS bean, you have to make it "managed", that is annotate MyController as (for instance) javax.annotation.ManagedBean or as a javax.ejb.Stateless.
Also beware that in case of webapp (.war), the beans.xml file has to be located in the WEB-INF folder !
In a Spring XML configuration, I have the followings:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
....
</bean>
and in a Java class, I have
#Autowired
private SessionFactory sessionFactory;
without a setter. That works.
Now, I change the sessionFactory to a Java configuration as the followings.
#Configuration
#EnableTransactionManagement
#PropertySource({ "classpath:jdbc.properties" })
public class PersistenceConfig {
#Bean
public SessionFactory sessionFactory() {
LocalSessionFactoryBuilder lsfb = new LocalSessionFactoryBuilder(dataSource());
lsfb.addAnnotatedClasses(...);
lsfb.setProperties(hibernateProperties());
return lsfb.buildSessionFactory();
}
// ...
}
And I get an error "could not autowire field". Adding a setter doesn't help. Why the sessionFactory can't get autowired with a Java configuration?
BTW, I can work around this problem by having a Java configuration for the DAO as well.
I see that there is no #ComponentScan annotation on your #Configuration class, so probably the problem is in how you import this configuration. Please ensure that all particular beans live in the same context or at least that PersistenceConfig is parent to the context in which you are autowiring SessionFactory
I have added the #ComponentScan annotation and it doesn't solve the problem. The annotation tells Spring to look for any #Components to configure as beans. This problem seems to me is that during the process of creating a bean with #Component, it can't find a bean configured in my Java configuration file which is started in WebAppInitializer.
I have a simple java class which displays "waiting" text on execution , in "TMSCore" java project.
package com.stock.bo;
public class example {
/**
* #param args
*/
public static void main(String[] args) {
// ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println("================================> waiting");
}
}
I have created TMSCore.jar and have set this example.class as entry point ,of my jar file.
Then i have created a module for this project in C:\Jboss\jboss-as-7.1.1\modules\org\tms\main , and pasted the jar in the same path
then i have created module.xml and pasted in the same path
module.xml
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="org.tms">
<resources>
<resource-root path="TMSCore.jar"/>
</resources>
</module>
then i have created a jboss-deployment-structure.xml in my webproject/web-inf directory
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.tms"/>
</dependencies>
</deployment>
</jboss-deployment-structure>
when i start the server with my war containing above jboss-deployment-structure.xml, in my console its showing deployed TMSCore.jar
but my "waiting" text in my jar is not displayed on console
my requirement is i should get "================================> waiting" on my console once jboss is started up
or else can any one can suggest how to make a jar to execute on starting jboss server?
BTW i am using JBOSS7.1
If I am right it's because JBoss doesn't execute a library, it only loads the classes contained in the jar file. So putting a main function and generating an executable jar will not help.
If your goal is to have an global module on the server, I suggest you these modifications:
Create the module (as you have already done)
Declare it as dependency in jboss-deployment-structure.xml (as you have already done)
Declare it as global module on the server, so it will be loaded only once by JBoss. Edit the configuration file standalone.xml and modify the section:
<subsystem xmlns="urn:jboss:domain:ee:1.0">
<global-modules>
<module name="org.tms" />
</global-modules>
</subsystem>
Now you have a module that have classes loaded only once. I you need to have only one instance of your Example class, the I suggest you to use an singleton:
public class Example {
// The only one instance
private static Example instance;
// Private constructor to avoid creation of other instances of this class
private Example()
{
System.out.println("================================> waiting");
}
public static Example getInstance()
{
if(instance == null)
{
instance = new Example();
}
return instance;
}
}
Then to use it in all projects on the server
Example ex = Example.getInstance();
will give you back the existing instance (or create one the first time).
Notice: I can't try, so no guarantee that that will work.
Edit: Maybe a small modification of the Example class can also make it run during the classes loading:
public class Example {
// The only one instance
private static Example instance = new Example();
// Private constructor to avoid creation of other instances of this class
private Example()
{
System.out.println("================================> waiting");
}
public static Example getInstance()
{
return instance;
}
}
Again: not tested.
You can't run a jar, but you can execute a startup method in a singleton.
#Startup
#Singleton
public class FooBean {
#PostConstruct
void atStartup() { ... }
#PreDestroy
void atShutdown() { ... }
}
This will happen at application start up and shutdown. I'd call the function you need from there.
See http://docs.oracle.com/javaee/6/tutorial/doc/gipvi.html
I have created three assemblies. A web site, a WCF service and a contracts assembly that holds the interfaces that the services implement. I would like to use Castle Windsor to create the services for me on the client (website) so that I do not have to have an endpoint in the web.config of the web site for each service that I wish to use.
I would like to look at the contract assembly and get all the service interfaces in a namespace. Right now for every service I have something like the following when registering the components with the container.
container.Register(Component.For<ChannelFactory<IMyService>>().DependsOn(new { endpointConfigurationName = "MyServiceEndpoint" }).LifeStyle.Singleton);
container.Register(Component.For<IMyService>().UsingFactoryMethod((kernel, creationContext) => kernel.Resolve<ChannelFactory<IMyService>>().CreateChannel()).LifeStyle.PerWebRequest);
and in my web.config I have the setup code.
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="AuthToken" type="MyNamespace.Infrastructure.AuthTokenBehavior, MyNamespace.Contracts" />
</behaviorExtensions>
</extensions>
<behaviors>
<endpointBehaviors>
<behavior>
<AuthToken />
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00">
<readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647"></readerQuotas>
<security mode="None" />
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint name="MyServiceEndpoint" address="http://someurl/MyService.svc" binding="wsHttpBinding" contract="MyNamespace.Contracts.IMyService"></endpoint>
</client>
</system.serviceModel>
I end up with multiple service endpoints that all look almost exactly the same and when we deploy onto clients machines they have to set the address of every endpoint even though the base url is the same for every one.
I would like to have a base url in my web.config that is grabbed through code and then have the services registered with the container using reflection on the contracts assembly. I do need the specialised endpoint behaviour that is in the above config file.
Where so I start? the WcfFacility looks great but the doco is a bit lacking...
I agree the docs for the wcf facility are lacking and that is sad because it is a really great tool and it would be a real shame if people didn't use it because they could not get started, so let me see if I can help you out a little bit if I can...
Let's create a three project application that has:
A class library for shared contracts
A console application that acts as a server
A console application that acts as a client
The idea is that we want to be able to use the service names when we register the services and to share a base URL (I think that is what you were asking and if not, hopefully you can extrapolate from here). So, firstly, the shared contracts simply has this in it (nothing special, normal WCF fare):
[ServiceContract]
public interface IMyService1
{
[OperationContract]
void DoSomething();
}
[ServiceContract]
public interface IMyService2
{
[OperationContract]
void DoSomethingToo();
}
Now the server console application looks like this, we firstly implement the service contracts (again nothing special there, just classes implementing interfaces) and then just register them all as services (notice no need for any configuration file here and you can change the way you decide what are services etc using all the options that Windsor gives you - my scheme is a bit limited but it gives you an idea):
namespace Services
{
public class MyService1 : IMyService1
{
public void DoSomething()
{
}
}
public class MyService2 : IMyService2
{
public void DoSomethingToo()
{
}
}
}
//... In some other namespace...
class Program
{
// Console application main
static void Main()
{
// Construct the container, add the facility and then register all
// the types in the same namespace as the MyService1 implementation
// as WCF services using the name as the URL (so for example
// MyService1 would be http://localhost/MyServices/MyService1) and
// with the default interface as teh service contract
var container = new WindsorContainer();
container.AddFacility<WcfFacility>(
f => f.CloseTimeout = TimeSpan.Zero);
container
.Register(
AllTypes
.FromThisAssembly()
.InSameNamespaceAs<MyService1>()
.WithServiceDefaultInterfaces()
.Configure(c =>
c.Named(c.Implementation.Name)
.AsWcfService(
new DefaultServiceModel()
.AddEndpoints(WcfEndpoint
.BoundTo(new WSHttpBinding())
.At(string.Format(
"http://localhost/MyServices/{0}",
c.Implementation.Name)
)))));
// Now just wait for a Q before shutting down
while (Console.ReadKey().Key != ConsoleKey.Q)
{
}
}
}
And that is the server, now how to consume these services? Well, actually that is quite easy, here is a client console application (it references just the contracts class library):
class Program
{
static void Main()
{
// Create the container, add the facilty and then use all the
// interfaces in the same namespace as IMyService1 in the assembly
// that contains the aforementioned namesapce as WCF client proxies
IWindsorContainer container = new WindsorContainer();
container.AddFacility<WcfFacility>(
f => f.CloseTimeout = TimeSpan.Zero);
container
.Register(
Types
.FromAssemblyContaining<IMyService1>()
.InSameNamespaceAs<IMyService1>()
.Configure(
c => c.Named(c.Implementation.Name)
.AsWcfClient(new DefaultClientModel
{
Endpoint = WcfEndpoint
.BoundTo(new WSHttpBinding())
.At(string.Format(
"http://localhost/MyServices/{0}",
c.Name.Substring(1)))
})));
// Now we just resolve them from the container and call an operation
// to test it - of course, now they are in the container you can get
// hold of them just like any other Castle registered component
var service1 = container.Resolve<IMyService1>();
service1.DoSomething();
var service2 = container.Resolve<IMyService2>();
service2.DoSomethingToo();
}
}
That's it - hopefully this will get you started (I find that experimenting and using the intellisense usually gets me where I need to go). I showed you both the service and client sides but you can just use one or the other if you prefer.
You should be able to see where the binding is configured and how I have gone about constructing the URLs so in your case you could easily just pluck your base URL from a configuration file or whatever you want to do.
One last thing to mention is that you can add your custom endpoint behaviour by adding it as an extension to the endpoint, so in the client example you would have something like this:
Endpoint = WcfEndpoint
.BoundTo(new WSHttpBinding())
.At(string.Format("http://localhost/MyServices/{0}", c.Name.Substring(1)))
.AddExtensions(new AuthTokenBehavior())
I am new on JBossCache. Reading the user documentation it says that a listener could be added to the Eviction class used, but I wasn't able to found how to do add one to the configuration file, or how that should be added.
I have tried to add an #CacheListener with a method #NodeEvicted, but that method
#CacheListener
public class EvictionListener {
#NodeEvicted
public void nodeEvicted(NodeEvent ne) {
System.out.println("Se borro el nodo");
}
}
and add it to the cache instance
CacheFactory factory = new DefaultCacheFactory();
this.cache = factory.createCache();
EvictionListener listener = new EvictionListener();
this.cache.create();
this.cache.addCacheListener(listener);
but the sysout isn't executed. For testing it, I am just running a simple Main value.
This is the configuration value I am using:
<jbosscache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:jboss:jbosscache-core:config:3.2">
<transaction transactionManagerLookupClass="org.jboss.cache.transaction.GenericTransactionManagerLookup"/>
<eviction wakeUpInterval="20">
<default algorithmClass="org.jboss.cache.eviction.FIFOAlgorithm" wakeUpInterval="20">
<property name="maxNodes" value="20" />
</default>
</eviction>
</jbosscache>
The problem was solved because I wasn't reading the XML configuration file.
I was missing:
factory.createCache(file);