Below are my code snippet for using WritableComparator, but it does not work
import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.io.WritableComparator;
public class MovieComparator extends WritableComparator{
public MovieComparator(){
super(Movie.class);
}
#Override
public int compare(WritableComparable o,WritableComparable o2){
System.out.println("in compare");
Movie m = (Movie)o;
Movie m2 = (Movie)o2;
System.out.println(m.compareTo(m2));
return m.movieId.compareTo(m2.movieId);
}
}
public class Movie implements WritableComparable {
Text movieId;
Text movieTitle;
public Movie(Text movieId, Text movieTitle) {
this.movieId = movieId;
this.movieTitle = movieTitle;
}
public Movie(){
}
public String getMovieId() {
return movieId.toString();
}
public void setMovieId(String movieId) {
this.movieId = new Text(movieId);
}
public String getMovieTitle() {
return movieTitle.toString();
}
public void setMovieTitle(String movieTitle) {
this.movieTitle = new Text(movieTitle);
}
#Override
public void readFields(DataInput in) throws IOException {
//movieId = in.read;
movieId.readFields(in);
movieTitle.readFields(in);
}
#Override
public void write(DataOutput out) throws IOException {
//out.writeUTF(movieId);
//out.writeUTF(movieTitle);
movieId.write(out);
movieTitle.write(out);
}
#Override
public int compareTo(Movie o) {
// System.out.println("in compareTo");
int res=movieTitle.compareTo(o.movieTitle);
return res;
}
#Override
public int hashCode(){
return movieId.hashCode();
}
#Override
public boolean equals(Object o){
Movie m=(Movie)o;
return movieId.equals(m.movieId);
}
#Override
public String toString(){
return movieTitle.toString();
}
}
In driver class I am setting the comparator by below line
job.setSortComparatorClass(MovieComparator.class);
Can any body tell me where I am wrong in this at it gives exception below
14/09/08 14:17:03 WARN mapred.LocalJobRunner: job_local_0001
java.io.IOException: Spill failed
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.collect(MapTask.java:1029)
at org.apache.hadoop.mapred.MapTask$NewOutputCollector.write(MapTask.java:691)
at org.apache.hadoop.mapreduce.TaskInputOutputContext.write(TaskInputOutputContext.java:80)
at com.impetus.MovieMapper.map(MovieMapper.java:44)
at com.impetus.MovieMapper.map(MovieMapper.java:1)
at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:144)
at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:764)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:370)
at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:212)
I found the issue that Instead of using super(Movie.class), I will have to use super(Movie.class,true). As by sending true, WritableComparator will instantiate the object other wise it will pass null in compare method
Related
I want that user roles uploaded from db in keycloak. I have wrote RoleSPI for this, but roles don't load. My role-provider is displayed on server info.
I
I created CustomRoleProvider:
public class CustomRoleProvider implements RoleProvider {
#Override
public RoleModel addRealmRole(RealmModel realmModel, String s, String s1) {
return null;
}
#Override
public Stream<RoleModel> getRealmRolesStream(RealmModel realmModel, Integer integer, Integer integer1) {
return null;
}
#Override
public Stream<RoleModel> getRolesStream(RealmModel realmModel, Stream<String> stream, String s, Integer integer, Integer integer1) {
return null;
}
#Override
public boolean removeRole(RoleModel roleModel) {
return false;
}
#Override
public void removeRoles(RealmModel realmModel) {
}
#Override
public RoleModel addClientRole(ClientModel clientModel, String s, String s1) {
return null;
}
#Override
public Stream<RoleModel> getClientRolesStream(ClientModel clientModel, Integer integer, Integer integer1) {
return null;
}
#Override
public void removeRoles(ClientModel clientModel) {
}
#Override
public void close() {
}
#Override
public RoleModel getRealmRole(RealmModel realmModel, String s) {
System.out.println("getRealmRole()");
return roleModel;
}
#Override
public RoleModel getRoleById(RealmModel realmModel, String s) {
System.out.println("getRoleById()");
return roleModel;
}
#Override
public Stream<RoleModel> searchForRolesStream(RealmModel realmModel, String s, Integer integer, Integer integer1) {
System.out.println("searchForRolesStream()");
return roleModelStream;
}
#Override
public RoleModel getClientRole(ClientModel clientModel, String s) {
System.out.println("getClientRole()");
return roleModel;
}
#Override
public Stream<RoleModel> searchForClientRolesStream(ClientModel clientModel, String s, Integer integer, Integer integer1) {
System.out.println("searchForClientRolesStream()");
return roleModelStream;
}
}
My CustomRoleProviderFactory:
public class CustomRoleProviderFactory implements RoleProviderFactory {
#Override
public RoleProvider create(KeycloakSession keycloakSession) {
System.out.println("create");
return new CustomRoleProvider();
}
#Override
public void init(Config.Scope scope) {
}
#Override
public void postInit(KeycloakSessionFactory keycloakSessionFactory) {
}
#Override
public void close() {
}
#Override
public String getId() {
return "role-provider";
}
}
I noticed that the create method was not called after the start of keycloak.
There is org.keycloak.models.RoleProviderFactory in resources\META-INF\services packages:
com.healthec.keycloak.provider.CustomRoleProviderFactory
Do you have any ideas why roles don't loaded?
public class Tool extends Item {
#Override
public Item clone() throws CloneNotSupportedException
{
return super.clone();
}
}
clone() method is giving me an error:
Cannot directly invoke the abstract method clone() for the type Item
Item class is a abstract class which implements Cloneable interface.
public class CloneTest {
static abstract class Item implements Cloneable {
private boolean stackable;
protected String name;
public Item() {
this.name = new String("Air");
this.stackable = true;
}
public Item(String name) {
this.name = name;
this.stackable = true;
}
public Item(String name, boolean stackable) {
this.name = name;
this.stackable = stackable;
}
public String getName() {
return this.name;
}
public void setName(String n) {
this.name = n;
}
#Override
public boolean equals(Object rhs) {
Item r = (Item) rhs;
return (this.name).equals(r.name);
}
#Override
public int hashCode() {
return this.name.hashCode();
}
public boolean isStackable() {
return this.stackable;
}
public abstract void read(Scanner s);
#Override
public Item clone() throws CloneNotSupportedException {
Object obj = super.clone();
// Add some custom logic here... like initializing few members
return (Item) obj;
}
#Override
public String toString() {
return (" " + this.name);
}
}
public static class Tool extends Item {
#Override
public Item clone() throws CloneNotSupportedException {
return super.clone();
}
#Override
public void read(Scanner s) {
}
}
public static void main(String[] args) throws CloneNotSupportedException
{
Tool tool1 = new Tool();
System.out.println(tool1);
Object tool2 = tool1.clone();
System.out.println(tool2);
System.out.println(tool1 == tool2);
}
}
I want to convert this generic class to a parcelable object, but I don't have very clear the concepts of the issue.
Class:
public class Type<T> implements Parcelable {
// T stands for "Type"
private T t;
public void set(T t) { this.t = t; }
public T get() { return t; }
}
This is what I've tried,. but I know that this is not correct, or maybe this is not complete.
public class Type<T> implements Parcelable {
// T stands for "Type"
private T t;
protected Type(Parcel in) {
}
public void set(T t) { this.t = t; }
public T get() { return t; }
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
}
public static final Creator< Type > CREATOR = new Creator< Type >() {
#Override
public Type createFromParcel(Parcel in) {
return new Type(in);
}
#Override
public Type[] newArray(int size) {
return new Type[size];
}
};
}
This is similar approach as vikas kumar but guarantte that you can pass only Parcelable as T parameter so you avoid exception.
public class Type<T extends Parcelable> implements Parcelable {
private T t;
protected Type(Parcel in) {
t = (T) in.readValue(t.getClass().getClassLoader());
}
public static final Creator<Type> CREATOR = new Creator<Type>() {
#Override
public Type createFromParcel(Parcel in) {
return new Type(in);
}
#Override
public Type[] newArray(int size) {
return new Type[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeValue(t);
}
}
Your generic data type may cause runtime error
so make sure you implements Parcelable and also the class you are passing should implement Parcelable otherwise it will cause runtime error.
public class Type<T extends Parcelable> implements Parcelable {
// T stands for "Type"
private T t;
public void set(T t) { this.t = t; }
public T get() { return t; }
protected Type(Parcel in) {
final String className = in.readString();
try {
t = in.readParcelable(Class.forName(className).getClassLoader());
} catch (ClassNotFoundException e) {
Log.e("readParcelable", className, e);
}
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeValue(t);
}
#SuppressWarnings("unused")
public static final Parcelable.Creator<Type> CREATOR = new Parcelable.Creator<Type>() {
#Override
public Type createFromParcel(Parcel in) {
return new Type(in);
}
#Override
public Type[] newArray(int size) {
return new Type[size];
}
};
}
I need to change NaN value and Minus sign in NumberFormat's NumberConstants.
It's impossible to change NumberConstants "on the fly", so I decided to subclass NumberFormat.
NumberFormat's constructor annotation says:
#param numberConstants the locale-specific number constants to use for
this format -- NOTE subclasses passing their own instance here
should pay attention to {#link #forcedLatinDigits()} and remap
localized symbols using {#link #createLatinNumberConstants(NumberConstants)}
It seemes what I should call setForcedLatinDigits(true) in order method createLatinNumberConstants(NumberConstants) to be executed. Then localized constants will be updated by that (createLatinNumberConstants) method, and I will get NumberConstants which I need.
Here is my code:
public class MyNumberFormat extends NumberFormat {
protected MyNumberFormat(String pattern, CurrencyData cdata, boolean userSuppliedPattern) {
this(defaul, pattern, cdata, userSuppliedPattern);
}
protected MyNumberFormat(NumberConstants numberConstants, String pattern, CurrencyData cdata, boolean userSuppliedPattern) {
super(numberConstants, pattern, cdata, userSuppliedPattern);
}
public static MyNumberFormat getFormat(String pattern) {
return new MyNumberFormat(pattern, CurrencyList.get().getDefault(), true);
}
protected static NumberConstants createLatinNumberConstants(
final NumberConstants orig) {
final String groupingSeparator = remapSeparator(
orig.groupingSeparator());
final String decimalSeparator = remapSeparator(
orig.decimalSeparator());
final String monetaryGroupingSeparator = remapSeparator(
orig.monetaryGroupingSeparator());
final String monetarySeparator = remapSeparator(
orig.monetarySeparator());
return new NumberConstants() {
#Override
public String currencyPattern() {
return orig.currencyPattern();
}
#Override
public String decimalPattern() {
return orig.decimalPattern();
}
#Override
public String decimalSeparator() {
return decimalSeparator;
}
#Override
public String defCurrencyCode() {
return orig.defCurrencyCode();
}
#Override
public String exponentialSymbol() {
return orig.exponentialSymbol();
}
#Override
public String globalCurrencyPattern() {
return orig.globalCurrencyPattern();
}
#Override
public String groupingSeparator() {
return groupingSeparator;
}
#Override
public String infinity() {
return orig.infinity();
}
#Override
public String minusSign() {
return UnicodeSymbols.MINUS;
}
#Override
public String monetaryGroupingSeparator() {
return monetaryGroupingSeparator;
}
#Override
public String monetarySeparator() {
return monetarySeparator;
}
#Override
public String notANumber() {
return "?";
}
#Override
public String percent() {
return orig.percent();
}
#Override
public String percentPattern() {
return orig.percentPattern();
}
#Override
public String perMill() {
return orig.perMill();
}
#Override
public String plusSign() {
return orig.plusSign();
}
#Override
public String scientificPattern() {
return orig.scientificPattern();
}
#Override
public String simpleCurrencyPattern() {
return orig.simpleCurrencyPattern();
}
#Override
public String zeroDigit() {
return "0";
}
};
}
}
So in order to format number i will execute this:
String fmt(final Double x){
MyNumberFormat.setForcedLatinDigits(true);
MyNumberFormat format = MyNumberFormat.getFormat("0.0000");
return format.format(x)
}
But in fact createLatinNumberConstants is protected static method and it can't be overriden or substituted.
So MyNumberFormat.createLatinNumberConstants() is never executed.
What am I doing wrong?
I think you do not need to overwrite createLatinNumberConstants - instead you pass your number constants to the constructor of the super class.
as a base you can use the default number constants of NumberFormat.
Something like that should work:
public class MyNumberFormat extends NumberFormat {
protected MyNumberFormat(String pattern, CurrencyData cdata, boolean userSuppliedPattern) {
super(createMyNumberConstants(NumberFormat.defaultNumberConstants), pattern, cdata, userSuppliedPattern);
}
public static MyNumberFormat getFormat(String pattern) {
return new MyNumberFormat(pattern, CurrencyList.get().getDefault(), true);
}
protected static final NumberConstants createMyNumberConstants(
final NumberConstants orig) {
return new NumberConstants() {
#Override
public String currencyPattern() {
return orig.currencyPattern();
}
#Override
public String decimalPattern() {
return orig.decimalPattern();
}
#Override
public String decimalSeparator() {
return decimalSeparator();
}
#Override
public String defCurrencyCode() {
return orig.defCurrencyCode();
}
#Override
public String exponentialSymbol() {
return orig.exponentialSymbol();
}
#Override
public String globalCurrencyPattern() {
return orig.globalCurrencyPattern();
}
#Override
public String groupingSeparator() {
return orig.groupingSeparator();
}
#Override
public String infinity() {
return orig.infinity();
}
#Override
public String minusSign() {
return orig.minusSign();
}
#Override
public String monetaryGroupingSeparator() {
return orig.monetaryGroupingSeparator();
}
#Override
public String monetarySeparator() {
return orig.monetarySeparator();
}
#Override
public String notANumber() {
return "?";
}
#Override
public String percent() {
return orig.percent();
}
#Override
public String percentPattern() {
return orig.percentPattern();
}
#Override
public String perMill() {
return orig.perMill();
}
#Override
public String plusSign() {
return orig.plusSign();
}
#Override
public String scientificPattern() {
return orig.scientificPattern();
}
#Override
public String simpleCurrencyPattern() {
return orig.simpleCurrencyPattern();
}
#Override
public String zeroDigit() {
return "0";
}
};
}
I am getting an error for the following code in a java web app--
XStream xstream = new XStream();
apiresponse myClassObject;
myClassObject= xstream.fromXML(resp);
The error is shown for the line of code just above this line--
error="Type mismatch- cannot convert from Object to apiresponse"
Given below is the XML that I have to parse---
<apiresponse version="1" xmlns="http://ahrefs.com/schemas/api/links/1">
<resultset_links count="2">
<result>
<source_url>http://ahrefs.com/robot/</source_url>
<destination_url>http://blog.ahrefs.com/</destination_url>
<source_ip>50.22.24.236</source_ip>
<source_title>Ahrefs – backlinks research tool</source_title>
<visited>2011-08-31T07:56:53Z</visited>
<anchor>Blog</anchor>
<rating>257.674000</rating>
<link_type>text</link_type>
<is_nofollow>false</is_nofollow>
</result>
<result>
<source_url>http://apps.vc/</source_url>
<destination_url>http://ahrefs.com/robot/</destination_url>
<source_ip>64.20.55.86</source_ip>
<source_title>Device info</source_title>
<visited>2011-08-27T18:59:31Z</visited>
<anchor>http://ahrefs.com/robot/</anchor>
<rating>209.787100</rating>
<link_type>text</link_type>
<is_nofollow>false</is_nofollow>
</result>
</resultset_links>
</apiresponse>
I have created the following java classes to obtain data from above xml---
package com.arvindikchari.linkdatasmith.domain;
final public class apiresponse {
protected resultset_links rlinks;
public apiresponse() {
}
public resultset_links getRlinks()
{
return rlinks;
}
public setRlinks(resultset_links rlinks)
{
this.rlinks=rlinks;
}
}
final public class resultset_links {
protected List<result> indiv_result = new ArrayList<result>();
public resultset_links() {
}
public List<result> getIndiv_result()
{
return List;
}
public void setIndiv_result(List<result> indiv_result)
{
this.indiv_result=indiv_result;
}
}
final public class result {
protected String source_url;
protected String destination_url;
protected String source_ip;
protected String source_title;
protected String visited;
protected String anchor;
protected String rating;
protected String link_type;
public result() {
}
public String getSource_url()
{
return source_url;
}
public void setSource_url(String source_url)
{
this.source_url=source_url;
}
public String getDestination_url()
{
return destination_url;
}
public void setDestination_url(String destination_url)
{
this.destination_url=destination_url;
}
public String getSource_ip()
{
return source_ip;
}
public void setSource_ip(String source_ip)
{
this.source_ip=source_ip;
}
public String getSource_title()
{
return source_title;
}
public void setSource_title(String source_title)
{
this.source_title=source_title;
}
public String getVisited()
{
return visited;
}
public void setVisited(String visited)
{
this.visited=visited;
}
public String getAnchor()
{
return anchor;
}
public void setAnchor(String anchor)
{
this.anchor=anchor;
}
public String getRating()
{
return rating;
}
public void setRating(String rating)
{
this.rating=rating;
}
public String getLink_type()
{
return link_type;
}
public void setLink_type(String link_type)
{
this.link_type=link_type;
}
}
What am I doing wrong here?
You have many errors, but the one corresponding to your message is you have to cast the result of xstream.fromXML to an apiresponse' object :
apiresponse result = (apiresponse)xstream.fromXML(resp);
Moreover, the code you provided (the Java classes) do not compile, there are many errors.
Here are some improvements :
Result.java :
#XStreamAlias("result")
public class Result {
protected String source_url;
protected String destination_url;
protected String source_ip;
protected String source_title;
protected String visited;
protected String anchor;
protected String rating;
protected String link_type;
protected Boolean is_nofollow;
public Result() {
}
public String getSource_url()
{
return source_url;
}
public void setSource_url(String source_url)
{
this.source_url=source_url;
}
public String getDestination_url()
{
return destination_url;
}
public void setDestination_url(String destination_url)
{
this.destination_url=destination_url;
}
public String getSource_ip()
{
return source_ip;
}
public void setSource_ip(String source_ip)
{
this.source_ip=source_ip;
}
public String getSource_title()
{
return source_title;
}
public void setSource_title(String source_title)
{
this.source_title=source_title;
}
public String getVisited()
{
return visited;
}
public void setVisited(String visited)
{
this.visited=visited;
}
public String getAnchor()
{
return anchor;
}
public void setAnchor(String anchor)
{
this.anchor=anchor;
}
public String getRating()
{
return rating;
}
public void setRating(String rating)
{
this.rating=rating;
}
public String getLink_type()
{
return link_type;
}
public void setLink_type(String link_type)
{
this.link_type=link_type;
}
public Boolean getIs_nofollow() {
return is_nofollow;
}
public void setIs_nofollow(Boolean is_nofollow) {
this.is_nofollow = is_nofollow;
}
ResultsetLinks.java :
#XStreamAlias("resultset_links")
public class ResultsetLinks {
#XStreamImplicit(itemFieldName="result")
protected List<Result> indivResult = new ArrayList<Result>();
public ResultsetLinks() {
}
public List<Result> getResult()
{
return indivResult;
}
public void setResult(List<Result> indiv_result)
{
this.indivResult =indiv_result;
}
}
ApiResponse.java :
#XStreamAlias("apiresponse")
public class ApiResponse {
#XStreamAlias("resultset_links")
protected ResultsetLinks rlinks;
public ApiResponse() {
}
public ResultsetLinks getRlinks()
{
return rlinks;
}
public void setRlinks(ResultsetLinks rlinks)
{
this.rlinks=rlinks;
}
}
And finally your code to unmarshall the XML :
XStream xstream = new XStream();
xstream.processAnnotations(ApiResponse.class);
xstream.processAnnotations(ResultsetLinks.class);
xstream.processAnnotations(Result.class);
ApiResponse result = (ApiResponse)xstream.fromXML(resp);
All this code is working fine with Xstream 1.4.2
Try to follow Sun's coding convention for your classes name, attributes names, etc...
Use XstreamAliases to adapt the Java class name to the XML name.