spring.net used in a class library - spring.net

I am attempting to use spring.net 's IoC conatiner in a class library which in and of itself is not an executable. A web project simply calls this library , this library contains the references to the spring binaries and to spring's config files.
Essentially the question is:
Does spring.net need to reside in an executable to start, or canit reside in a classs library that will be referenced by an executable?
Any help will be appreciated.

You can include part of your configuration in the class library project as an embedded resource file. Let's say you called it LibraryConfig.xml. Then in your executable's application config file, you include the embedded resource using the assembly: prefix. Here's an example:
<spring>
<context type="Spring.Context.Support.XmlApplicationContext, Spring.Core">
<resource uri="assembly://FooLibrary/FooLibrary/LibraryConfig.xml"/>
<resource uri="config://spring/objects" />
</context>
<objects xmlns="http://www.springframework.net">
<object id="mainForm" type="FooApp.MainForm, FooApp">
<!-- mainController is some object defined in LibraryConfig.xml -->
<property name="Controller" ref="mainController"/>
</object>
</objects>
</spring>
If your main application doesn't need to use Spring itself, I think you can set up the whole application context in the library. Embed the config file as described above, then define a singleton object to hold the application context and load it from the embedded config file. Finally, you need to define some kind of factory methods for the client code to create your classes with. The factory methods can either go on the singleton itself (probably using generics), or have a separate factory method on each class that needs to be instantiated. Those factory methods make the actual requests from the application context and the client code never sees it.

it can reside in a dll which is referenced by an executable, but make sure that the configuration is included in (or referenced by) the executable's config file.

Related

Is There A Way to have Struts 2 Resource Bundle Point to a File Location?

I currently have a package on my class path called MyResources with multiple property files that struts uses. Works great:
<constant name="struts.custom.i18n.resources" value="com.company.MyResources"/>
I am trying to move the properties files to a file location, so they can be updated without having to rebuild the package. Is it possible in Struts 2 to refer to this file location?
For example, my new file location with the properties files is:
/g01/properties/
And I would like Struts to use that location for the resource.
Yes, by providing an implementation of ResourceBundleTextProvider and initializing it in your struts.xml configuration file.
The default implementation, com.opensymphony.xwork2.TextProviderSupport defers the text lookup to com.opensymphony.xwork2.util.LocalizedTextUtil.
There are a number of ways to go about this, but if you don't need any of the default S2 behavior, here's the place to start:
<bean type="com.opensymphony.xwork2.TextProvider" name="struts"
class="com.opensymphony.xwork2.TextProviderSupport" scope="default" />
Provide your own ResourceBundleTextProvider implementation that uses whatever configuration management you want, for example, we implemented a DB-backed version (with caching, of course) that allowed translations to live in, and be managed by, a normal DB and I18N front end.
I'll see if I can dig up my original work this weekend and provide a link to a stripped-down solution.
The location of the file cannot be off the class path when you run your app. You should determine which classloader is used to load the resource. Then you should find a way to configure this classloader to be able to use the location as resource. So, it's possible. A short answer.

Blueprint dependency injection within a bundle

I've come across a case where I want to use Blueprint (Aries) to resolve a dependency at run-time and the implementation is defined in the same bundle which requires it and will not be used in any other bundles. I am abstracting the implementation within this bundle to make it easier to mock the dependency when unit testing. If I put this service in its own bundle, it would lead to poor cohesion.
At run-time, the Blueprint says it is waiting for dependencies. How can I use Blueprint to realize dependency injection within a bundle?
<!-- Interface -->
<reference id="modelEntityMapper" interface="org.example.blog.rest.cxf.server.model.ModelEntityMapper" />
<!-- Implementation defined within same bundle -->
<bean id="modelEntityMapperImpl" class="org.example.blog.rest.cxf.server.model.impl.ModelEntityMapperImpl" />
<service ref="modelEntityMapperImpl" interface="org.example.blog.rest.cxf.server.model.ModelEntityMapper" />
<!-- Object which has dependency -->
<bean id="posts" class="org.example.blog.rest.cxf.server.BlogResourceImpl">
<property name="modelEntityMapper" ref="modelEntityMapper" />
</bean>
Edit
I just tried the suggestion from #christian-scheider and Blueprint is still waiting for some service to satisfy ModelEntityMapper
The XML
<!-- Interface -->
<reference id="modelEntityMapper" interface="org.example.blog.rest.cxf.server.model.ModelEntityMapper" />
<!-- Implementation defined within same bundle -->
<bean id="modelEntityMapperImpl" class="org.example.blog.rest.cxf.server.model.impl.ModelEntityMapperImpl" />
<!-- Object which has dependency -->
<bean id="posts" class="org.example.blog.rest.cxf.server.BlogResourceImpl">
<property name="modelEntityMapper" ref="modelEntityMapperImpl" />
</bean>
The Log
Bundle rest-cxf-server is waiting for dependencies [(objectClass=org.example.blog.rest.cxf.server.model.ModelEntityMapper)]
Can you just refer to the bean of the service directly? If you define the service and the service reference in the same blueprint file then using an OSGi service does not make that much sense.
I was unable to find detailed documentation on the Aries site related to referencing in bundles, so I'm going to reference the Eclipse Gemini Blueprint implementation documentation (formerly Spring Dynamic Modules). See the warning in section 9.2.1.1 of their documentation. Yes, technically this is related to their implementation, but I believe it's likely a similar story in Aries.
It is an error to declare a mandatory reference to a service that is also exported by the same bundle, this behaviour can cause application context creation to fail through either deadlock or timeout.
In a nutshell you typically either import (reference) an OSGi service or you export an OSGi service in the same bundle, usually you don't try to do both in a single bundle.
If you want this bundle to export a service of type ModelEntityMapper, then you'll need to export it with the service element. When other beans need a reference within the same bundle, you would use the ref attribute like you're using it. In this case, you would not need the reference element at all, but instead use the service element.
If you're not going to use the ModelEntityMapper bean outside of this bundle, you don't need to use a reference or service element in the configuration at all. You should be able to use it in the ref attribute without exporting it as an OSGi service - it's basically a bean internal to that bundle. In this case, you should be able to remove the reference element altogether: the <bean id="modelEntityMapperImpl" ... will create a bean internal to the bundle, and the <property name="modelEntityMapper" ref="modelEntityMapperImpl" /> element should be able to use that bean internally to the bundle.
If you want to import a reference of type ModelEntityMapper from OSGi if available, else use an internally defined fallback, that gets more complicated. You'd have to declare a non-mandatory reference and inject that reference into your class along with the internally defined bean and then have defaulting logic that checks the availability of them. Alternatively you could just define the implementation in a separate bundle from the interface.

Facelet Tag Library mechanism does not work as expected

I'm unable to pack taglibrary in a war file. I moved tags from project to extra library the current project is depending now. I put the taglibrary file into the META-INF directory of the jar containing tags (how is described here). But the page does not work:
Expression Error: Named Object: eu.barbucha.barbatag.simple.PropertyTag not found.
The server is able to find the taglibrary. Otherwise the page works, just one waring appears:
Warning: This page calls for XML namespace http://barbucha.eu/tags declared with prefix br but no taglibrary exists for that namespace.
Thus the question is: Why the server finds just the descriptor, but not the classes? When I copy classes from WEB-INF/lib/barbatag.jar into WEB-INF/classes and restart the webapp in administration console, the page gets working. The server also finds UI-components only if they are involved directly in classes of the applictation, but not in the jar stored in the WEB-INF/lib directory. On other hand the server loads taglib descriptor from the jar. It's really confusing... Declaration of the critical class:
package eu.barbucha.barbatag.simple;
#FacesComponent("eu.barbucha.barbatag.simple.PropertyTag")
public class PropertyTag extends UIComponentBase { ... }
Definition of critical tag:
<tag>
<display-name>The component taking values from a property file</display-name>
<tag-name>property</tag-name>
<component>
<component-type>eu.barbucha.barbatag.simple.PropertyTag</component-type>
</component>
</tag>
One potentionally important point: I'm using Spring MVC.
You need to supply a /META-INF/faces-config.xml file in the JAR in order to get JSF to scan the JAR file for classes with JSF specific annotations like #FacesComponent. This is done so to prevent JSF from unnecessarily scanning every single JAR file for classes (which might be very time and CPU consuming if you have lot of them).

bean-validation validation.xml ignored

I am using JSR 303 Bean validation in my JSF 2.0 web application and it works fine with annotations. Now I would like to ignore annotations and configure validation rules using the validation.xml file, so this is what I did (I am using an eclipse dynamic web project) :
Added validation.xml under WebContent/META-INF/validation.xml
<?xml version="1.0" encoding="UTF-8"?>
<validation-config
xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration validation-configuration-1.0.xsd"
>
<constraint-mapping>META-INF/validation/constraint-mapping.xml</constraint-mapping>
</validation-config>
Then created the file constraint-mapping.xml under WebContent/META-INF/validation/constraint-mapping.xml
<constraint-mappings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd"
xmlns="http://jboss.org/xml/ns/javax/validation/mapping">
<bean class="my.full.path.ValidationMB" ignore-annotations="true">
</bean>
</constraint-mappings>
Having these configurations in place, I suppose the annotations in my bean class ValidationMB shall be ignored, BUT this is not happening!, which makes me assume that the validation.xml file is not being loaded.
any ideas? thanks.
Environment:
Apache Tomcat 7.0.23
javax.faces-2.1.4.jar
hibernate-validator-4.2.0.Final.jar
hibernate-validator-annotation-processor-4.2.0.Final.jar
validation-api-1.0.0.GA.jar
slf4j-api-1.6.1.jar
From the spec: section 4.4.6. XML Configuration: META-INF/validation.xml
Unless explicitly ignored by calling
Configuration.ignoreXMLConfiguration(), a Configuration takes into
account the configuration available in META-INF/validation.xml. This
configuration file is optional but can be used by applications to
refine some of the Bean Validation behavior. If more than one
META-INF/validation.xml file is found in the classpath, a
ValidationException is raised.
To solve my problem I had to create a META-INF folder under the project src folder, which ends in the WEB-INF/classes/META-INF.
The structure of the web application is:
ROOT
|_META-INF -- don't put validation.xml here
|_WEB-INF
|__ classes
|_META-INF
|__validation.xml
But I think that if I pack my web application in a jar file and reuse it in another project It may not work, I will let you know later once I do it.
Try to put your validation.xml directly into the WEB-INF/ directory.
I stumbled across this while looking for something else but wanted to clarify to the OP what is happening. You do in fact need the file to exist at META-INF/validation.xml; however, that is relative to the classpath which is why it worked when you put it under WEB-INF/classes/META-INF/validation.xml.
The cleaner approach is to let the file be put there for you. Your Eclipse project should already be outputting whatever is in your source directory to WEB-INF/classes somehow for you or nothing would be running. But sometimes there are filters on what it outputs so it might excluding something. You might want to check your src dirs and make sure they don't have exclusions.
Just as an example, if you had a Maven war project, all of your java sources would go in src/main/java and the generated classes would end up in the WEB-INF/classes directory. The equivalent happens for src/main/resources which contains non-source files. When I want *.xml, *.properties, etc. to end up in WEB-INF/classes I put them in src/main/resources. For your example I would have a src/main/resources/META-INF/validation.xml file.
Hope this helps anyone else who comes across this and is confused.

Does anyone have documentation on CustomActivitiesAndExtensions.xml?

I found this mentioned in a few books I have on TFS2010, but the documentation is pretty sparse, and searching on Google and Bing returns nothing I don't already know.
Does anyone have and detailed information on the using CustomActivitiesAndExtensions.xml and how it works?
The CustomActivitiesAndExtensions.xml file is primarily used to specify additional activities and/or workflow extensions to be loaded by the Build Service to support your build process.
Here's an example:
<?xml version="1.0" encoding="utf-8"?>
<Assemblies DownloadListedItemsOnly="true">
<Assembly LoadListedItemsOnly="true" FileName="CustomAssembly.dll" HostEnvironmentOption="All">
<Activities>
<Activity FullName="CustomAssembly.OnAgentActivity" HostEnvironmentOption="Agent"/>
<Activity FullName="CustomAssembly.OnControllerActivity" HostEnvironmentOption="Controller"/>
<Activity FullName="CustomAssembly.OnBothActivity" HostEnvironmentOption="All"/>
</Activities>
<Extensions>
<Extension FullName="CustomAssembly.OnAgentExtension" HostEnvironmentOption="Agent"/>
<Extension FullName="CustomAssembly.OnControllerExtension" HostEnvironmentOption="Controller"/>
<Extension FullName="CustomAssembly.OnBothExtension" HostEnvironmentOption="All"/>
</Extensions>
</Assembly>
</Assemblies>
The DownloadListedItemsOnly attribute is an optimization you can use to only download the assemblies specified in this file and ignore any others.
Lastly, it's important to note that if you specify an assembly beneath the Activities or Extensions element that doesn't actually have an Activity or Extension (as appropriate) that's discoverable via reflection, then that assembly won't be loaded. The most likely case where this would be a problem would be if you implemented the design-time experience for your activity in a separate assembly.
As you you know TFS based on WF so you just need the documentation of how to create WF custom activity, To create a basic custom activity, you inherit from the Activity class or a derived type. To create a custom composite activity, you inherit from the CompositeActivity class or a derived type.
See this link:
Creating Custom Activities

Resources