No measurement ServiceProvider found - java

I'm researching the unit of measure open source library, and the maven dependency I use is:
<dependency>
<groupId>tec.units</groupId>
<artifactId>unit-ri</artifactId>
<version>1.0.2</version>
</dependency>
which implements the JSR-363. When I try to use it as below:
ServiceProvider provider = ServiceProvider.current();
The result is:
Exception in thread "main" java.lang.IllegalStateException: No measurement ServiceProvider found.
Could anybody tell me what is wrong?

I faced with the same problem using the measure library in the java bean forms while opening beans within the Netbeans IDE. This trick works for me:
import javax.measure.spi.ServiceProvider;
import tec.units.ri.spi.DefaultServiceProvider;
private ServiceProvider serviceProvider;
try {
serviceProvider = ServiceProvider.current();
} catch ( IllegalStateException e ) {
serviceProvider = new DefaultServiceProvider();
}

So, I have looked into the class ServiceProvider to see what the current() method does:
https://github.com/unitsofmeasurement/unit-api/blob/master/src/main/java/javax/measure/spi/ServiceProvider.java
You can see it uses the ServiceLoader to return a value. If you look at the documentation of the ServiceLoader you will see that you need a config file:
https://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html
A service provider is identified by placing a provider-configuration file in the resource directory META-INF/services. The file's name is the fully-qualified binary name of the service's type. The file contains a list of fully-qualified binary names of concrete provider classes, one per line. Space and tab characters surrounding each name, as well as blank lines, are ignored. The comment character is '#' ('\u0023', NUMBER SIGN); on each line all characters following the first comment character are ignored. The file must be encoded in UTF-8.

For everyone who may need to use this library. It is strange but after i change the maven dependency version from 1.02 to 1.01,no other change,it works fine. So , this should be a bug of this version...

Related

Configuring global list of allowed classes for serialization

I am using Inifinispan v12.1 with String Boot v2.5.2 via org.infinispan:infinispan-spring-boot-starter-embedded. In our application we are using custom classes which we would like to cache (very common case), however it turned out that starting from v10 these classes need to be listed in "allow list".
We are using infinispan.xml configuration passed via infinispan.embedded.config-xml property as advised by sample project.
Question: How is it possible to configure allow list globally for all caches by the means of XML configuration file?
I have considered the following options:
System property infinispan.deserialization.allowlist.regexps (from ClassAllowList) – not good choice as configuration will be spread between XML file and e.g. some other place. More over if the property is renamed in future Infinispan versions one would notice it only when application is run.
Defining the <cache-container><serialization><allow-list> as to documentation is not good option because will result several identical per-cache XML configuration blocks.
The corresponding Java Config for Spring Boot application would be:
#org.springframework.context.annotation.Configuration
public class InfinispanConfiguration {
#Bean
public InfinispanGlobalConfigurationCustomizer globalCustomizer() {
return builder -> builder.allowList().addRegexp("^org\\.mycompany\\.");
}
}
P.S. Javadoc in GlobalConfiguration assumes that there is <default> XML section the configuration can be read from, but in fact XML does not support it anymore.
P.P.S. Arguably the dots in the packages should be escaped in SpringEmbeddedModule and start with ^ because ClassAllowList uses Matcher#find() (boolean regexMatch = compiled.stream().anyMatch(p -> p.matcher(className).find());):
serializationAllowList.addRegexps("^java\\.util\\..*", "^org\\.springframework\\..*");

Getting WebSphere full server name using JNDI

At the top of the WebSphere log file, I see a couple of lines:
WebSphere Platform 8.5 blah blah running with process name abc\xyz\pqr and process id 1234
Full server name is abc\xyz\pqr-1234
I would like to get the value pqr shown in the above two lines using Java code in my application that runs on the WebSphere server. I found that I could get the values abc and xyz by doing JNDI lookup, based on this answer to another question:
(new InitialContext()).lookup("thisNode/cell/cellname").toString(); // returns "abc"
(new InitialContext()).lookup("thisNode/nodename").toString(); // returns "xyz"
However, JNDI lookup of "servername" does not return pqr or any of the values above, but something else entirely.
How can I get the value pqr (or the entire value abc\xyz\pqr or abc\xyz\pqr-1234, whichever is possible)? I would prefer to get the value by doing a JNDI lookup rather than by using a WebSphere class like com.ibm.websphere.runtime.ServerName as mentioned here, but if that is not possible I can use any solution that works.
I realize there may be questions about why I need to get the value and perhaps even opinions that it may not be a good practice to get that value etc. However, I have a valid and unavoidable reason for doing that.
Here is a link to a document about how to capture a WebSphere namespace dump, including example output, showing entries such as,
(top)/nodes/outpost/nodename
(top)/nodes/outpost/servers/server1/servername
Have you tried a look up of the following?
thisNode/servers/thisServer/servername
Well this answer is not a JNDI solution, however it is a solution to this problem. WebSphere provides class com.ibm.websphere.runtime.ServerName which is used for exactly this scenario. It has bunch of utility methods like:
getDisplayName()
getServerId()
getFullName()
So how to use this class in your project while still being able to deploy project on a non-websphere environments? By checking in runtime if you are running within WebSphere, and if you do, than invoking methods within ServerName.
In order to not pollute your project with unnecessary dependencies to was runtime create a new utility jar project and add dependencies:
com.ibm.ws.runtime-xxxx.jar as provided dependency (part of was or was client)
spring-core-xxxx.jar as runtime dependency
Rest of the solutions are in following two methods withing two classes. One which checks for presence of websphere and other which interacts with it:
import org.springframework.util.ClassUtils;
public class WasInfo {
/**
* #return a map populated with relevant WebSphere names
* if running on WebSphere or empty one if not
*/
public Map<String, String> about() {
ClassLoader currentClassLoader = this.getClass().getClassLoader();
boolean isWebsphere = ClassUtils.isPresent("com.ibm.websphere.runtime.ServerName", currentClassLoader);
if (!isWebsphere ) {
return new HashMap<>();
}
WebSphereConfig wc = new WebSphereConfig();
return wc.resolveServerName();
}
}
import com.ibm.websphere.runtime.ServerName;
public class WebSphereConfig {
public Map<String, String> resolveServerName() {
// expecting 'cell/node/server' pattern
String serverFullName = ServerName.getFullName();
String serverName = ServerName.getDisplayName();
Map<String, String> map = new HashMap<>();
map.put("serverFullName", serverFullName);
map.put("serverName", serverName);
String[] segments = serverFullName.split("\\\\");
if (segments.length == 3) {
map.put("cellName", segments[0]);
map.put("nodeName", segments[1]);
}
}
}
I used Spring's ClassUtils to get rid of some boring code in this example. And for exercise one could invoke ServerName methods using reflections. That would remove a need for import ServerName statement and make code even more "simpler". But idea would remain the same.

Axis2 error: Invalid white space character (0x4) in text to output

I have created a Java client to interact with a SOAP webservice using Axis2 (1.7.6) as code generator. The problem is with some inputs the client is throwing an exception with the message:
org.apache.axis2.AxisFault: Invalid white space character (0x4) in text to output (in xml 1.1, could output as a character entity)
It seems the serialiser is hitting some chars considered invalid to XML spec. I have seen that problem around but no definitive answer or the fix. I'm not using Spring or any other dependency injection framework, it's a standalone application, so I need to configure the inners of Axis2 by hand.
Any ideas on how to fix/configure the client properly?
After some research I found this behaviour is due to one default setting of the lib Woodstox (Axis2 dependency), that uses the class com.ctc.wstx.api.InvalidCharHandler.FailingHandler as default implementation of the interface com.ctc.wstx.api.InvalidCharHandler, used inside com.ctc.wstx.sw.XmlWriter and invoked in the serialisation process. This means: when the component hits characters considered invalid to XML, it’ll throw an error.
Woodstox provides another implementation of the interface com.ctc.wstx.api.InvalidCharHandler, the one called com.ctc.wstx.api.InvalidCharHandler.ReplacingHandler that instead of throwing errors will replace those chars for something else. But how to do that?
The class com.ctc.wstx.stax.WstxOutputFactory inside Woodstox contains several configurations, one of them being the invalid char handler. Though, it's not configurable by some magic system wide property, instead, by the method com.ctc.wstx.stax.WstxOutputFactory#setProperty, that takes as arguments one string and one object.
So first, you'll have to extend that factory and set the property com.ctc.wstx.outputInvalidCharHandler with an instance of com.ctc.wstx.api.InvalidCharHandler.ReplacingHandler that takes as argument the char you want to replace the invalid ones with. Like this:
package my.package;
import com.ctc.wstx.stax.WstxOutputFactory;
public class MyWstxOutputFatory extends WstxOutputFactory {
public MyWstxOutputFatory() {
setProperty(
com.ctc.wstx.api.WstxOutputProperties.P_OUTPUT_INVALID_CHAR_HANDLER,
new com.ctc.wstx.api.InvalidCharHandler.ReplacingHandler(' '));
}
}
The second, trickiest and undocumented step is how to register your implementation as the factory Woodstox'll use. You'll have to create a file named META-INF/services/javax.xml.stream.XMLOutputFactory simply containing the name of your factory, in this case, the string:
my.package.MyWstxOutputFatory
Place this file in such a way it's included in your project's resulting jar. In my case I placed like: src/main/resources/META-INF/services/javax.xml.stream.XMLOutputFactory.
And you're done!

Automatically remove the file generated by Java 7 Annotation Processor when delete the annotation in source file

I am writing a java annotation processor for java 7 source code.
And surely, I can use javax.annotation.processing.filer to help me generate the file under project directory automatically.
ex: annotation is #becare
public interface test {
#becare
int compare(int a, int b);
}
my annotation processor's job is when it detects the given annotation #becare, it will generate the file for me.
My Question is that if I remove the annotation from the previous code snippet, can I let annotation processor to be aware that and delete the file it just created?
Or is there any workaround to help me achieve this ?
Thanks in advance.
When you create the generated file you declare that it's linked to your 'test' interface like this:
Elements eltUtils = processingEnv.getElementUtils();
filer.createSourceFile("testGenerated", eltUtils.getTypeElement("test"));
When the source is deleted, the processor will remove generated file like javadoc says:
If there are no originating elements, none need to be passed. This information may be used in an incremental environment to determine the need to rerun processors or remove generated files. Non-incremental environments may ignore the originating element information.

GRAILS: method for permalink/slug generation?

Does anybody have a quick method to generate slugs and permalinks in Grails 1.3.7/2.0.0.RC1?
The main restriction: this method should work with non-latin characters.
Russian/bulgarian cirillic, deutsch umlauts etc...
Any suggestions ?
Grails 2.0.0.RC1
From the 2.0.0.RC1 docs:
Link Generation API
A general purpose LinkGenerator class is now available that is usable
anywhere within a Grails application and not just within the context
of a controller. For example if you need to generate links in a
service or an asynchronous background job outside the scope of a
request:
LinkGenerator grailsLinkGenerator
def generateLink() { grailsLinkGenerator.link(controller:"book", action:"list") }
Although it's not stated explicitly, I assume the reference to grailsLinkGenerator is obtained via dependency injection
Grails 1.3.7
You can use either the createLink or resource tags to generate links. If you're generating permalinks, I assume you'll want these to be absolute URLs. If so, you'll need to use either the absolute or base attribute when using these tags.
If you use the absolute attribute, be sure to set the value of grails.serverURL in Config.groovy
Link Permanence
The text above describes how to generate links to resources in a Grails application, but doesn't say anything about how to make these links permanent. AFAIK, the link to a resource will always remain the same as long as you don't change anything that is used in the URL mapping scheme (as defined in UrlMappings.groovy)
By default the URL mapping scheme uses
the resource's ID
the controller name
the action name
So if you never change these for the links of interest, you should be good.
As easy as:
title.replaceAll("[\\W]+", "-")
That makes it.

Categories