I have a problem with getting a bean from application context when using Spring IoC.
I have a ContactProvider interface for my phone book application and 3 implementations of this interface. All implementations are Spring #Components. I also have a Preferences which stores which of the implementation is used by the user. When the user tries to change the implementation the application throws NoSuchBeanDefinitionException. To find out which implementation the user wants to use based on his input I created utility enum with all of my implementations that provides Class objects for all of the implementation. This class has fromString() method which returns implementation type based on given string (which is user input).
Method for setting a new contact provider:
private void handleSetProviderCommand(String param) {
ContactProviders providerType = ContactProviders.fromString(param);
Class<? extends ContactProvider> providerClass = providerType.getProviderClass();
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
ContactProvider contactProvider = context.getBean(providerClass); // I get NoSuchBeanDefinitionException here
phoneBook.setContactProvider(contactProvider);
Preferences preferences = Preferences.userNodeForPackage(PhoneBook.class);
preferences.put(PreferenceKeys.CONTACT_PROVIDER.getKey(), param);
}
ContactProviders enum, from which I take a class of the implementation:
public enum ContactProviders {
FILE(FileContactProvider.SHORT_NAME, FileContactProvider.class),
ELASTIC(ElasticContactProvider.SHORT_NAME, ElasticContactProvider.class),
NO_SQL(NoSqlContactProvider.SHORT_NAME, NoSqlContactProvider.class);
private final Class<? extends ContactProvider> providerClass;
private final String shortName;
ContactProviders(String shortName, Class<? extends ContactProvider> providerClass) {
this.shortName = shortName;
this.providerClass = providerClass;
}
public static ContactProviders fromString(String param) {
Optional<ContactProviders> providerType = Arrays.stream(ContactProviders.values())
.filter(cp -> cp.getShortName().equals(param)).findFirst();
if (providerType.isPresent()) {
return providerType.get();
} else {
throw new IllegalArgumentException("Contact provider not recognized: " + param);
}
}
}
One of the implementations (all of them are annotated with #Component):
public class FileContactProvider implements ContactProvider {
public static final String SHORT_NAME = "file";
private static final String SEPARATOR = "|";
private List<Contact> contacts;
private Path file;
private Logger logger = LoggerFactory.getLogger(FileContactProvider.class);
public FileContactProvider() {
file = openFile();
contacts = loadContacts();
}
private Path openFile() {
Preferences preferences = Preferences.userNodeForPackage(FileContactProvider.class);
Path file = Paths.get(
preferences.get(
PreferenceKeys.FILE_FILE_NAME.getKey(),
PreferenceKeys.FILE_FILE_NAME.getDefaultValue()
)
);
if (Files.exists(file)) {
try {
if (Files.isReadable(file) && Files.isWritable(file)) {
return file;
} else {
throw new IOException("The file is not readable or writable.");
}
} catch (IOException e) {
logger.error("Error while opening the file: " + e.getMessage());
}
} else {
try {
Files.createFile(file);
} catch (IOException e) {
logger.error("Error while creating a file: " + e.getMessage());
}
}
return file;
}
private void saveFile() {
List<String> contactStrings = new ArrayList<>();
contacts.stream()
.sorted()
.forEach(contact -> contactStrings.add(contact.getName() + SEPARATOR + contact.getNumber()));
try {
Files.write(file, contactStrings);
} catch (IOException e) {
logger.error("Error while saving to the file: " + e.getMessage());
}
}
private List<Contact> loadContacts() {
List<Contact> loaded = new ArrayList<>();
try {
Files.readAllLines(file)
.forEach(line -> {
String[] contactString = StringUtils.split(line, SEPARATOR);
Contact contact = new Contact(contactString[0], contactString[1]);
loaded.add(contact);
});
} catch (IOException e) {
logger.error("Error while reading file content: " + e.getMessage());
}
return loaded;
}
#Override
public Contact save(Contact contact) {
if (contacts.contains(contact)) {
System.out.println("Contact is already in the phone book.");
} else {
contacts.add(contact);
saveFile();
}
return contact;
}
#Override
public List<Contact> find(String name) throws ContactNotFoundException {
List<Contact> found = contacts.stream()
.filter(contact -> StringUtils.indexOf(contact.getName().toLowerCase(), name.toLowerCase()) != -1)
.collect(Collectors.toList());
if (found.isEmpty()) {
throw new ContactNotFoundException(name);
}
return found;
}
#Override
public List<Contact> getAll() {
return contacts;
}
#Override
public void delete(Contact contact) {
contacts.remove(contact);
saveFile();
}
#Override
public void configure() {
System.out.print("Enter file name: ");
String filename = ConsoleUtils.getInput("^[^<>:;,?\"*|/]+$");
Preferences preferences = Preferences.userNodeForPackage(FileContactProvider.class);
preferences.put(PreferenceKeys.FILE_FILE_NAME.getKey(), filename);
file = openFile();
contacts = loadContacts();
}
#Override
public void showConfiguration() {
Preferences preferences = Preferences.userNodeForPackage(FileContactProvider.class);
System.out.println("File name: " +
preferences.get(
PreferenceKeys.FILE_FILE_NAME.getKey(),
PreferenceKeys.FILE_FILE_NAME.getDefaultValue()
)
);
}
}
I also have a bean defined in my #Configuration class to provide a contact provider based on preference already set in the system. It takes preference string and creates an instance of implementation class to return:
#Bean
public ContactProvider contactProvider() {
Preferences preferences = Preferences.userNodeForPackage(PhoneBook.class);
String preferredProviderName = preferences.get(PreferenceKeys.CONTACT_PROVIDER.toString(),
ContactProviders.FILE.getShortName());
try {
Class<? extends ContactProvider> providerClass = ContactProviders.fromString(preferredProviderName)
.getProviderClass();
Constructor<? extends ContactProvider> constructor = providerClass.getConstructor();
return constructor.newInstance();
} catch (IllegalArgumentException e) {
logger.error("Can't get provider from given string: " + e.getMessage());
} catch (NoSuchMethodException e) {
logger.error("Can't find provider's constructor: " + e.getMessage());
} catch (IllegalAccessException e) {
logger.error("Can't get access to provider's constructor: " + e.getMessage());
} catch (InstantiationException e) {
logger.error("Can instantiate provider: " + e.getMessage());
} catch (InvocationTargetException e) {
logger.error("Can't invoke provider's constructor: " + e.getMessage());
}
logger.info("Couldn't get provider from preferences. Default file contact provider instantiated.");
return new FileContactProvider();
}
Related
I am trying to implement a save and load function in my program that saves an arrayList to a textfile and then can later load all of the past lists I have saved and print them out. I am currently using these two methods:
public static void save(Serializable data, String fileName) throws Exception {
try (ObjectOutputStream oos = new ObjectOutputStream((Files.newOutputStream(Paths.get(fileName))))) {
oos.writeObject(data);
}
}
public static Object load(String fileName) throws Exception {
try (ObjectInputStream oos = new ObjectInputStream((Files.newInputStream(Paths.get(fileName))))) {
return oos.readObject();
}
}
As well as a class that represents a list as serializable data.
The problem with this is that it won't save the data after I terminate the program, and when it loads data it prints it with a great deal of extra text besides the list I want it to return. Is there a better or easier way of doing this?
I once had a same problem. So I will show you how to do it ...
Be the below Level class is what is to be saved:
public class Level implements Serializable {
private int level = 1;
private int star;
private int point;
// Constructor
public Level() {
}
public void setLevel(int level) {
this.level = level;
}
public int getLevel() {
return level;
}
public void setStar(int stars) {
this.star = stars;
}
public int getStar() {
return star;
}
public void setPoint(int points) {
this.point = points;
}
public int getPoint() {
return point;
}
#Override
public String toString() {
return "Level-" + level + " " +
(star > 1 ? star + " stars": star + " star") + " " +
(point > 1 ? point + " points" : point + " point") + "\n";
}
}
We will save the list into this file:
private static final String FILENAME = "data.level";
This is the List of our objects:
List<Level> mLevels;
Call this method to save the list into the file:
private void save() {
if(mLevels.isEmpty()) {
return;
}
try
{
ObjectOutputStream oos = new ObjectOutputStream(mContext.openFileOutput(FILENAME, Context.MODE_PRIVATE));
oos.writeObject(mLevels);
}
catch (IOException e)
{
//Toast.makeText(mContext,e.getMessage(),Toast.LENGTH_SHORT).show();
}
}
Use this method to load the list from saved file. Notice, we cast the list of our object with this (List<Level>) ois.readObject(); in the method:
private void load() {
try
{
ObjectInputStream ois = new ObjectInputStream(mContext.openFileInput(FILENAME));
mLevels = (List<Level>) ois.readObject();
}
catch (IOException e)
{
//Toast.makeText(mContext,e.getMessage(),Toast.LENGTH_SHORT).show();
}
catch (ClassNotFoundException e)
{
//Toast.makeText(mContext,e.getMessage(),Toast.LENGTH_SHORT).show();
}
if(mLevels == null) {
mLevels = new ArrayList<>();
//Toast.makeText(mContext,"List created",Toast.LENGTH_SHORT).show();
}
}
By now, you should get the idea of how to save your own list.
So I'm using Spring to generate random stories and I am getting a NullPointerException on line 73 of the controller which is where I call the ApplicationContext to make a BeanFactory in the function that gets the beans (MadLib and PartOfSpeech classes) from text files. The context was working just fine before I added that function. What's wrong?
Edit: I do know what a NullPointerException is. I don't know why it's happening here. Also, it works when I comment out the constructor. I think the problem might be that I'm trying to call the context before it exists?
Edit 2: I tried moving the call to getBeansFromFiles() to the first GetMapping(links). This took away the NullPointerException, probably because the Controller bean had already been initialized, so the context existed. But while the MadLibs got added to the list, the beans were not created or at least not autowired. Is there a place I can put this call where both will work? Do I need to implement an interface that will make this call at the right time?
package controllers;
import...
#Controller
#RequestMapping(value = "/madLib")
public class MadLibController {
#Autowired
ApplicationContext context;
public MadLibController(){
getBeansFromFiles();
}
public PartOfSpeech pos(String path){
String input;
try {
input = utility.Util.readFile(path);
} catch (IOException e) {
e.printStackTrace();
input = "v";
}
return new PartOfSpeech(input);
}
public MadLib ml(String path){
String input;
System.out.println(new File("").getAbsolutePath());
try {
input = utility.Util.readFile(path);
} catch (IOException e) {
e.printStackTrace();
input = "v#V#v";
}
return new MadLib(input);
}
public void getBeansFromFiles() {
AutowireCapableBeanFactory beanFactory = context.getAutowireCapableBeanFactory();
File folder = new File("../../txt/ml");
File[] listOfFiles = folder.listFiles();
for (File file : listOfFiles){
System.out.println("File path: " + file.getPath());
MadLib ml = ml(file.getPath());
String beanName = ml.getId();
beanFactory.autowireBean(ml);
beanFactory.initializeBean(ml, beanName);
((MadLibList)context.getBean("madLibList")).getList().add(ml);
}
folder = new File("../../txt/pos");
listOfFiles = folder.listFiles();
for (File file : listOfFiles){
System.out.println("File path: " + file.getPath());
PartOfSpeech pos = pos(file.getPath());
String beanName = pos.getId();
beanFactory.autowireBean(pos);
beanFactory.initializeBean(pos, beanName);
}
}
/*#Bean("verb")
public PartOfSpeech verb(){
return pos("verb");
}
#Bean("hansel2")
public MadLib hansel2(){
return ml("hansel");
}
#Bean("lunch")
public MadLib lunch(){
return ml("lunch");
}*/
#GetMapping
public String links(Model model){
MadLibList list = (MadLibList)context.getBean("madLibList");
//list.getList().add(hansel2());
//list.getList().add(lunch());
model.addAttribute("madLibList", list);
return "madLibLinks";
}
#GetMapping("/{name}")
public String prompts(HttpServletRequest req, HttpServletResponse res,
Model model, #PathVariable("name") String name,
#RequestParam(value = "random", defaultValue = "false") String random){
MadLib madLib = (MadLib)context.getBean(name);
madLib.setAnswers(new ArrayList<String>(madLib.getPrompts().size()));
System.out.println("Answers: " + madLib.getAnswers());
if (random.equals("true")){
System.out.println("Prompts: " + madLib.getPrompts());
for (int i=0; i<madLib.getPrompts().size(); i++){
try {
String posBean = utility.Util.camelCase(madLib.getPrompts().get(i));
PartOfSpeech pos = (PartOfSpeech)context.getBean(posBean);
String word = pos.getWord();
System.out.println(word);
madLib.getAnswers().add(word);
} catch (Exception e) {
System.out.println("exception in randomizing answers for " + madLib.getPrompts().get(i));
System.out.println(e);
madLib.getAnswers().add("");
}
}
}
model.addAttribute("default", "");
model.addAttribute("madLib", madLib);
return "madLibPrompts";
}
#PostMapping(value = "/result")
public String result(Model model, #ModelAttribute("madLib") MadLib madLib, BindingResult result){
System.out.println(madLib.getAnswers().get(0));
//model.addAttribute(madLib);
return "madLibResult";
}
}
Implement BeanDefinitionRegistryPostProcessor and use beanFactory instead of context
package controllers;
import...
#Controller
#RequestMapping(value = "/madLib")
public class MadLibController implements BeanDefinitionRegistryPostProcessor {
#Autowired
ApplicationContext context;
ConfigurableListableBeanFactory beanFactory;
private BeanDefinitionRegistry registry;
public PartOfSpeech pos(String path){
String input;
try {
input = utility.Util.readFile(path);
} catch (IOException e) {
e.printStackTrace();
input = "v";
}
return new PartOfSpeech(input);
}
public MadLib ml(String path){
String input;
System.out.println(new File("").getAbsolutePath());
try {
input = utility.Util.readFile(path);
} catch (IOException e) {
e.printStackTrace();
input = "v#V#v";
}
return new MadLib(input);
}
public void getBeansFromFiles() {
File folder = new File("../../txt/ml");
File[] listOfFiles = folder.listFiles();
for (File file : listOfFiles){
System.out.println("File path: " + file.getPath());
MadLib ml = ml(file.getPath());
String beanName = ml.getId();
beanFactory.registerSingleton(beanName, ml);
((MadLib)beanFactory.getBean(beanName)).setId(ml.getId());
((MadLib)beanFactory.getBean(beanName)).setTitle(ml.getTitle());
((MadLib)beanFactory.getBean(beanName)).setAnswers(ml.getAnswers());
((MadLib)beanFactory.getBean(beanName)).setPrompts(ml.getPrompts());
((MadLib)beanFactory.getBean(beanName)).setStrings(ml.getStrings());
((MadLibList)beanFactory.getBean("madLibList")).getList().add(ml);
}
folder = new File("../../txt/pos");
listOfFiles = folder.listFiles();
for (File file : listOfFiles){
System.out.println("File path: " + file.getPath());
PartOfSpeech pos = pos(file.getPath());
String beanName = pos.getId();
beanFactory.registerSingleton(beanName, pos);
((PartOfSpeech)beanFactory.getBean(beanName)).setName(pos.getName());
((PartOfSpeech)beanFactory.getBean(beanName)).setWords(pos.getWords());
}
}
#GetMapping
public String links(Model model){
MadLibList list = (MadLibList)beanFactory.getBean("madLibList");
model.addAttribute("madLibList", list);
return "madLibLinks";
}
#GetMapping("/{name}")
public String prompts(HttpServletRequest req, HttpServletResponse res,
Model model, #PathVariable("name") String name,
#RequestParam(value = "random", defaultValue = "false") String random){
MadLib madLib = (MadLib)beanFactory.getBean(name);
//System.out.println(madLib);
madLib.setAnswers(new ArrayList<String>(madLib.getPrompts().size()));
System.out.println("Answers: " + madLib.getAnswers());
if (random.equals("true")){
System.out.println("Prompts: " + madLib.getPrompts());
for (int i=0; i<madLib.getPrompts().size(); i++){
try {
String posBean = utility.Util.camelCase(madLib.getPrompts().get(i));
PartOfSpeech pos = (PartOfSpeech)beanFactory.getBean(posBean);
String word = pos.getWord();
System.out.println(word);
madLib.getAnswers().add(word);
} catch (Exception e) {
System.out.println("exception in randomizing answers for " + madLib.getPrompts().get(i));
System.out.println(e);
e.printStackTrace();
madLib.getAnswers().add("");
}
}
}
model.addAttribute("default", "");
model.addAttribute("madLib", madLib);
return "madLibPrompts";
}
#PostMapping(value = "/result")
public String result(Model model, #ModelAttribute("madLib") MadLib madLib, BindingResult result){
System.out.println(madLib.getAnswers().get(0));
//model.addAttribute(madLib);
return "madLibResult";
}
#Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0) throws BeansException {
this.beanFactory = arg0;
getBeansFromFiles();
}
#Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry arg0) throws BeansException {
this.registry = arg0;
}
}
I have the following util class for looking up Remote EJB. It's currently duplicated in many places. How can I write it once and reuse and only pass the interface name to tell it which EJB I'm looking for.
I have limited knowledge of Java Generics.
#ApplicationScoped
public class ServiceLookupUtil {
public static final String JBOSS_EJB_CLIENT = "org.jboss.ejb.client.naming";
public static final String JBOSS_NAMING_CONTEXT = "jboss.naming.client.ejb.context";
private AddressService addressService;
private Context context;
private Logger log;
public ServiceLookupUtil() {
super();
}
#Inject
public ServiceLookupUtil(Logger log) {
this.log = log;
}
public AddressService lookupAddressService() {
if (addressService == null) {
try {
context = getInitialContext();
log.debug("Looking up: " + getLookupName());
addressService = (AddressService) context.lookup(getLookupName());
return addressService;
} catch (Exception ex) {
log.error("Could not get reference to AddressService ", ex);
} finally {
if (context != null) {
try {
context.close();
} catch (NamingException e) {
log.error(e.getMessage(), e);
}
}
}
}
return addressService;
}
public Context getInitialContext() {
try {
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.URL_PKG_PREFIXES, JBOSS_EJB_CLIENT);
jndiProperties.put(JBOSS_NAMING_CONTEXT, true);
return new InitialContext(jndiProperties);
} catch (NamingException e) {
log.error(e.getMessage(), e);
}
return context;
}
private String getLookupName() {
return "ejb:" + AddressService.APP_NAME + "/" + AddressService.MODULE_NAME + "/" + AddressService.BEAN_NAME + "!" + AddressService.class.getName();
}
}
Here is the answer (change APP_NAME, MODULE_NAME and BEAN_NAME_CONVETION_ADD):
#ApplicationScoped
public class ServiceLookupUtil {
public static final String JBOSS_EJB_CLIENT = "org.jboss.ejb.client.naming";
public static final String JBOSS_NAMING_CONTEXT = "jboss.naming.client.ejb.context";
private Map<String, Object> services = new HashMap<String, Object>();
private Context context;
#Inject
private Logger log;
private static final String APP_NAME = "";
private static final String MODULE_NAME = "module-ejb";
private static final String BEAN_NAME_CONVETION_ADD = "Impl";
public ServiceLookupUtil() {
super();
}
#SuppressWarnings("unchecked")
public <S> S lookupService(Class<S> clazz) {
if (services.get(clazz.getName()) == null) {
S service = null;
try {
context = getInitialContext();
String jndi = getLookupName(clazz);
log.debug("Looking up: " + jndi);
service = (S) context.lookup(jndi);
services.put(clazz.getName(), service);
return service;
} catch (Exception ex) {
log.error("Could not get reference to AddressService ", ex);
} finally {
if (context != null) {
try {
context.close();
} catch (NamingException e) {
log.error(e.getMessage(), e);
}
}
}
}
return (S)services.get(clazz.getName());
}
private Context getInitialContext() {
try {
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.URL_PKG_PREFIXES, JBOSS_EJB_CLIENT);
jndiProperties.put(JBOSS_NAMING_CONTEXT, true);
return new InitialContext(jndiProperties);
} catch (NamingException e) {
log.error(e.getMessage(), e);
}
return context;
}
private <S> String getLookupName(Class<S> clazz) {
return "ejb:" + APP_NAME + "/" + MODULE_NAME + "/" + clazz.getSimpleName() + BEAN_NAME_CONVETION_ADD + "!" + clazz.getName();
}
}
I have problem of playing back the recorded media file from red5 published stream, following is my code. I could see a file called out.flv is created, but this out.flv can not be played back.
public class Red5ClientTest {
private static Timer timer;
private static RTMPClient client;
private static String sourceStreamName;
private static int videoTs;
private static int audioTs;
private static FLVWriter writer;
private static int bytesRead =0;
public static void main(String[] args) throws IOException {
String sourceHost = "localhost";
int sourcePort = 1935;
String sourceApp = "oflaDemo";
sourceStreamName = "myStream";
timer = new Timer();
client = new RTMPClient();
String path = "c:\\temp\\out.flv";
File file = new File(path);
if (!file.exists()) {
file.createNewFile();
}
writer = new FLVWriter(file,true);
client.setStreamEventDispatcher(new StreamEventDispatcher());
client.setStreamEventHandler(new INetStreamEventHandler() {
public void onStreamEvent(Notify notify) {
System.out.printf("onStreamEvent: %s\n", notify);
ObjectMap<?, ?> map = (ObjectMap<?, ?>) notify.getCall().getArguments()[0];
String code = (String) map.get("code");
System.out.printf("<:%s\n", code);
if (StatusCodes.NS_PLAY_STREAMNOTFOUND.equals(code)) {
System.out.println("Requested stream was not found");
client.disconnect();
}
else if (StatusCodes.NS_PLAY_UNPUBLISHNOTIFY.equals(code)
|| StatusCodes.NS_PLAY_COMPLETE.equals(code)) {
System.out.println("Source has stopped publishing or play is complete");
client.disconnect();
}
}
});
client.setConnectionClosedHandler(new Runnable() {
public void run() {
if (writer != null) {
writer.close();
}
System.out.println("Source connection has been closed, proxy will be stopped");
System.exit(0);
}
});
client.setExceptionHandler(new ClientExceptionHandler() {
#Override
public void handleException(Throwable throwable) {
throwable.printStackTrace();
System.exit(1);
}
});
// connect the consumer
Map<String, Object> defParams = client.makeDefaultConnectionParams(sourceHost, sourcePort,
sourceApp);
// add pageurl and swfurl
defParams.put("pageUrl", "");
defParams.put("swfUrl", "app:/Red5-StreamRelay.swf");
// indicate for the handshake to generate swf verification data
client.setSwfVerification(true);
// connect the client
client.connect(sourceHost, sourcePort, defParams, new IPendingServiceCallback() {
public void resultReceived(IPendingServiceCall call) {
System.out.println("connectCallback");
ObjectMap<?, ?> map = (ObjectMap<?, ?>) call.getResult();
String code = (String) map.get("code");
if ("NetConnection.Connect.Rejected".equals(code)) {
System.out.printf("Rejected: %s\n", map.get("description"));
client.disconnect();
//proxy.stop();
}
else if ("NetConnection.Connect.Success".equals(code)) {
// 1. Wait for onBWDone
timer.schedule(new BandwidthStatusTask(), 2000L);
Object result = call.getResult();
System.out.println("Red5ClientTest.main()");
}
else {
System.out.printf("Unhandled response code: %s\n", code);
}
}
});
// keep sleeping main thread while the proxy runs
// kill the timer
//timer.cancel();
System.out.println("Stream relay exit");
}
/**
* Handles result from subscribe call.
*/
private static final class SubscribeStreamCallBack implements IPendingServiceCallback {
public void resultReceived(IPendingServiceCall call) {
System.out.println("resultReceived: " + call);
Object result = call.getResult();
System.out.println("results came {}" + result);
}
}
private static final class StreamEventDispatcher implements IEventDispatcher {
public void dispatchEvent(IEvent event) {
System.out.println("ClientStream.dispachEvent()" + event.toString());
try {
//RTMPMessage build = RTMPMessage.build((IRTMPEvent) event);
IRTMPEvent rtmpEvent = (IRTMPEvent) event;
ITag tag = new Tag();
tag.setDataType(rtmpEvent.getDataType());
if (rtmpEvent instanceof VideoData) {
videoTs += rtmpEvent.getTimestamp();
tag.setTimestamp(videoTs);
}
else if (rtmpEvent instanceof AudioData) {
audioTs += rtmpEvent.getTimestamp();
tag.setTimestamp(audioTs);
}
IoBuffer data = ((IStreamData) rtmpEvent).getData().asReadOnlyBuffer();
tag.setBodySize(data.limit());
tag.setBody(data);
try {
writer.writeTag(tag);
} catch (Exception e) {
throw new RuntimeException(e);
}
System.out.println("writting....");
}
catch (Exception e) {//IOException
e.printStackTrace();
}
}
}
private static final class BandwidthStatusTask extends TimerTask {
#Override
public void run() {
// check for onBWDone
System.out.println("Bandwidth check done: " + client.isBandwidthCheckDone());
// cancel this task
this.cancel();
// create a task to wait for subscribed
timer.schedule(new PlayStatusTask(), 1000L);
// 2. send FCSubscribe
client.subscribe(new SubscribeStreamCallBack(), new Object[] { sourceStreamName });
}
}
private static final class PlayStatusTask extends TimerTask {
#Override
public void run() {
// checking subscribed
System.out.println("Subscribed: " + client.isSubscribed());
// cancel this task
this.cancel();
// 3. create stream
client.createStream(new CreateStreamCallback());
}
}
/**
* Creates a "stream" via playback, this is the source stream.
*/
private static final class CreateStreamCallback implements IPendingServiceCallback {
public void resultReceived(IPendingServiceCall call) {
System.out.println("resultReceived: " + call);
int streamId = ((Number) call.getResult()).intValue();
System.out.println("stream id: " + streamId);
// send our buffer size request
if (sourceStreamName.endsWith(".flv") || sourceStreamName.endsWith(".f4v")
|| sourceStreamName.endsWith(".mp4")) {
client.play(streamId, sourceStreamName, 0, -1);
}
else {
client.play(streamId, sourceStreamName, -1, 0);
}
}
}
}
what could I be doing possibly wrong here?
Finally got it
public class TeqniRTMPClient {
private static final Logger logger = LoggerFactory.getLogger(MyRtmpClient.class);
public static void main(String args[]) throws IOException {
TeqniRTMPClient client = new TeqniRTMPClient("localhost", 1935, "oflaDemo", "myStream");
client.recordStream();
}
private RTMPClient client;
private ITagWriter writer;
private String sourceHost;
private int sourcePort;
private String sourceApp;
private String sourceStreamName;
private int lastTimestamp;
private int startTimestamp = -1;
public TeqniRTMPClient(String sourceHost, int sourcePort, String sourceApp,
String sourceStreamName) {
super();
this.sourceHost = sourceHost;
this.sourcePort = sourcePort;
this.sourceApp = sourceApp;
this.sourceStreamName = sourceStreamName;
}
public void recordStream() throws IOException {
client = new RTMPClient();
String path = "c:\\temp\\out.flv";
File file = new File(path);
if (!file.exists()) {
file.createNewFile();
}
FLVService flvService = new FLVService();
flvService.setGenerateMetadata(true);
try {
IStreamableFile flv = flvService.getStreamableFile(file);
writer = flv.getWriter();
}
catch (Exception e) {
throw new RuntimeException(e);
}
client.setStreamEventDispatcher(new StreamEventDispatcher());
client.setStreamEventHandler(new INetStreamEventHandler() {
public void onStreamEvent(Notify notify) {
System.out.printf("onStreamEvent: %s\n", notify);
ObjectMap<?, ?> map = (ObjectMap<?, ?>) notify.getCall().getArguments()[0];
String code = (String) map.get("code");
System.out.printf("<:%s\n", code);
if (StatusCodes.NS_PLAY_STREAMNOTFOUND.equals(code)) {
System.out.println("Requested stream was not found");
client.disconnect();
}
else if (StatusCodes.NS_PLAY_UNPUBLISHNOTIFY.equals(code)
|| StatusCodes.NS_PLAY_COMPLETE.equals(code)) {
System.out.println("Source has stopped publishing or play is complete");
client.disconnect();
}
}
});
client.setExceptionHandler(new ClientExceptionHandler() {
#Override
public void handleException(Throwable throwable) {
throwable.printStackTrace();
System.exit(1);
}
});
client.setConnectionClosedHandler(new Runnable() {
public void run() {
if (writer != null) {
writer.close();
}
System.out.println("Source connection has been closed, proxy will be stopped");
System.exit(0);
}
});
// connect the consumer
Map<String, Object> defParams = client.makeDefaultConnectionParams(sourceHost, sourcePort,
sourceApp);
// add pageurl and swfurl
defParams.put("pageUrl", "");
defParams.put("swfUrl", "app:/Red5-StreamRelay.swf");
// indicate for the handshake to generate swf verification data
client.setSwfVerification(true);
// connect the client
client.connect(sourceHost, sourcePort, defParams, new IPendingServiceCallback() {
public void resultReceived(IPendingServiceCall call) {
System.out.println("connectCallback");
ObjectMap<?, ?> map = (ObjectMap<?, ?>) call.getResult();
String code = (String) map.get("code");
if ("NetConnection.Connect.Rejected".equals(code)) {
System.out.printf("Rejected: %s\n", map.get("description"));
client.disconnect();
}
else if ("NetConnection.Connect.Success".equals(code)) {
// 1. Wait for onBWDone
client.createStream(new CreateStreamCallback());
Object result = call.getResult();
System.out.println("Red5ClientTest.main()");
}
else {
System.out.printf("Unhandled response code: %s\n", code);
}
}
});
}
class CreateStreamCallback implements IPendingServiceCallback {
public void resultReceived(IPendingServiceCall call) {
System.out.println("resultReceived: " + call);
int streamId = ((Number) call.getResult()).intValue();
System.out.println("stream id: " + streamId);
// send our buffer size request
if (sourceStreamName.endsWith(".flv") || sourceStreamName.endsWith(".f4v")
|| sourceStreamName.endsWith(".mp4")) {
client.play(streamId, sourceStreamName, 0, -1);
}
else {
client.play(streamId, sourceStreamName, -1, 0);
}
}
}
class StreamEventDispatcher implements IEventDispatcher {
private int videoTs;
private int audioTs;
public void dispatchEvent(IEvent event) {
System.out.println("ClientStream.dispachEvent()" + event.toString());
try {
IRTMPEvent rtmpEvent = (IRTMPEvent) event;
logger.debug("rtmp event: " + rtmpEvent.getHeader() + ", "
+ rtmpEvent.getClass().getSimpleName());
if (!(rtmpEvent instanceof IStreamData)) {
logger.debug("skipping non stream data");
return;
}
if (rtmpEvent.getHeader().getSize() == 0) {
logger.debug("skipping event where size == 0");
return;
}
byte dataType = rtmpEvent.getDataType();
ITag tag = new Tag();
tag.setDataType(dataType);
if (rtmpEvent instanceof VideoData) {
VideoData video = (VideoData) rtmpEvent;
FrameType frameType = video.getFrameType();
videoTs += rtmpEvent.getTimestamp();
tag.setTimestamp(videoTs);
}
else if (rtmpEvent instanceof AudioData) {
audioTs += rtmpEvent.getTimestamp();
tag.setTimestamp(audioTs);
}
IoBuffer data = ((IStreamData) rtmpEvent).getData().asReadOnlyBuffer();
tag.setBodySize(data.limit());
tag.setBody(data);
try {
writer.writeTag(tag);
}
catch (Exception e) {
throw new RuntimeException(e);
}
System.out.println("writting....");
}
catch (Exception e) {//IOException
e.printStackTrace();
}
}
}
}
I want to use jASEN in my Java project, in order to retrieve the spam score for a set of emails I have.
My code is as follows:
public static double Get_jASEN_Score(MimeMessage mm) {
double jASEN_score = -1;
try {
// Initialise the scanner
JasenScanner.getInstance().init();
JasenScanResult result = JasenScanner.getInstance().scan(mm);
jASEN_score = result.getProbability();
} catch (JasenException e) {
Console.Console.Print_To_Console(String.format("jASEN Spam filter Error: %s", e.getMessage()), true, false);
}
return jASEN_score;
}
The problem is that the: JasenScanner.getInstance().init(); line process time is everlasting. I placed the "jasen-conf" folder at the right place.
Any suggest what is the problem?
try this:
private static final JasenScanner JASEN_SCANNER = JasenConnection.getInstance();
public static double getJASENScore(MimeMessage message) {
try {
JasenScanResult result = JASEN_SCANNER.scan(message);
return result.getProbability();
} catch (JasenException ex) {
LOGGER.info("JASON error; " + ex.getMessage());
}
return -1;
}
edit:
public class JasenConnection {
private static JasenScanner jasenScanner;
protected JasenConnection() {
try {
JasenScanner.getInstance().init();
ErrorHandlerBroker.getInstance().setErrorHandler(new EmptyErrorHandler());
jasenScanner = JasenScanner.getInstance();
} catch (JasenException ex) {
//LOGGER.info(ex.getMessage());
}
}
public static JasenScanner getInstance() {
if (null == jasenScanner) {
new JasenConnection();
}
return jasenScanner;
}
}